rest.js: repos.getReleases (octet-stream) fails with XML response "Only one auth mechanism allowed"
While trying to download the binary content of a release for a private repo, the server returns a 400 error:
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>InvalidArgument</Code>
<Message>Only one auth mechanism allowed; only the X-Amz-Algorithm query parameter, Signature query string parameter or the Authorization header should be specified</Message>
<ArgumentName>Authorization</ArgumentName>
<ArgumentValue>token {my auth token}</ArgumentValue>
<RequestId>...</RequestId>
<HostId>...</HostId>
</Error>
octokit:rest debug output:
{
timeout: 0,
agent: undefined,
method: 'get',
url: 'https://api.github.com/repos/{org}/{repo}/releases/assets/8110464',
headers: {
accept: 'application/octet-stream',
'user-agent': 'octokit/rest.js v15.9.5',
authorization: 'token {myAuthToken}'
},
body: undefined
}
A cursory googling tells me that this is related to extra headers being sent with the S3 request, but I can’t figure out how to modify them.
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 1
- Comments: 20 (9 by maintainers)
Commits related to this issue
- no auth when downloading asset see https://github.com/octokit/rest.js/issues/967 — committed to github/setup-licensed by deleted user 4 years ago
The cause of the issue is redirect URLs for assets in the GitHub API now include an auth token.
Most libraries keep the same headers when following redirects, so this ends up with a situation where auth is being added in the headers and then again in the redirect URL.
The GitHub API doesn’t like multiple auth mechanisms, so returns an error.
Seems to be a change made yesterday.
A workaround for
fetch:Is anyone looking into this? It just broke my app completely out of the sudden. Has something changed?
I can confirm this is still a problem. Managed to get it working with this approach:
There is a workaround which might work for you. The current problem is the
Authorizationheader.The GitHub API allows to alternatively pass the authorization headers as parameter.
You could get the request options and then send them with the
@octokit/requestpackage, so no authorization header is send by default.You might in this case use a different request library which supports streams, so you don’t need to await the entire download but write the response directly into the file you are writing, it will be much more memory efficient. You could do it with
node-fetchwhich we use internally, this wouldn’t add any new dependencies to your app.