Axios config headers causes requests to fail with ERR_INVALID_CHAR
See original GitHub issueDescribe 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]
Issue Analytics
- State:
- Created a year ago
- Reactions:18
- Comments:15
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.I am having the same issue, had to downgrade to version below 1.0.0