axios: Axios config headers causes requests to fail with ERR_INVALID_CHAR
Describe the bug
When using the error.config
property of an AxiosError to resubmit a request, the below error is thrown. Prior to version 1.x, this solution worked perfectly.
TypeError [ERR_INVALID_CHAR]: Invalid character in header content ["0"]
at ClientRequest.setHeader (node:_http_outgoing:647:3)
at new ClientRequest (node:_http_client:284:14)
at Object.request (node:http:97:10)
at RedirectableRequest._performRequest (test\node_modules\follow-redirects\index.js:284:24)
at new RedirectableRequest (test\node_modules\follow-redirects\index.js:66:8)
at Object.request (test\node_modules\follow-redirects\index.js:523:14)
at dispatchHttpRequest (test\node_modules\axios\dist\node\axios.cjs:2327:21)
at new Promise (<anonymous>)
at httpAdapter (test\node_modules\axios\dist\node\axios.cjs:2060:10)
at Axios.dispatchRequest (test\node_modules\axios\dist\node\axios.cjs:3158:10) {
code: 'ERR_INVALID_CHAR'
}
After looking through the code, it appears that there are two issues at play. The first one is that when an existing instance of AxiosHeaders is passed as a parameter to the new AxiosHeaders function, the headers from the previous instance are not correctly read.
The second issue is there when the config passed to the axios function is merged with the default headers, the output header object fails to merge with the default header object as the header object in the config passed to the axios function is an instance of AxiosHeaders not a plain object.
Sample header instance from the error.config.headers
AxiosHeaders {
'X-Custom-Header': 'foobar',
'User-Agent': 'axios/1.1.2',
'Accept-Encoding': 'gzip, deflate, br',
[Symbol(defaults)]: { Accept: 'application/json, text/plain, */*' }
}
Sample header instance that causes the error to be thrown
AxiosHeaders {
'[object Object]': undefined,
[Symbol(defaults)]: { '0': [Function: get] }
}
To Reproduce
Please see the code snippet below to reproduce the issue (or on RunKit).
const axios = require('axios');
const express = require('express');
const app = express();
app.get('/500', (req, res) => {
res.status(500).send('Internal Server Error');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
const test500 = async () => {
try {
const response = await axios.get('http://localhost:3000/500', {
headers: { 'X-Custom-Header': 'foobar' },
});
console.log(response.data);
} catch (error) {
console.log(error.config.headers);
await axios(error.config);
}
};
test500();
Expected behaviour
In the above example, the expected outcome is that the request would fail again with an error code 500, however in a real-world scenario, you could wait for x amount of time before retrying the request again.
Environment
- Axios Version [1.x.x]
- Adapter [HTTP]
- Node.js Version [18.10.0]
- OS: [Windows 11, Ubuntu 22.04]
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 24
- Comments: 23
Commits related to this issue
- fix: ignore non header values (#5089) — committed to EugeneSnikhovskiy/axios by EugeneSnikhovskiy 2 years ago
Experiencing the same issue, v1.1.3, tho tested on browser(firefox) / react, the error i got:
DOMException: Invalid header name.
. Found you can use the dumb json conversion to work around this issue like:when checked
transformed to:
not sure where the
Content-Type
went off to. Whilst sketchy it works.Having the same issue with axios-retry library! “axios”: “1.2.1”, “axios-retry”: “3.3.1”,
Came up with the following fix.
I am having the same issue, had to downgrade to version below 1.0.0
This appears to be fixed in
axios@1.2.0
and higher.