Summary
When cooldown is not configured (the default), the npm handler requests upstream metadata with Accept: application/vnd.npm.install-v1+json (abbreviated packuments). Some upstream registries — specifically JFrog Artifactory npm virtual repositories — return 406 Not Acceptable for this content type. The proxy then logs "failed to fetch npm metadata" error="upstream returned 406" and returns 502 to the client.
The only way to force Accept: application/json (which Artifactory accepts) is to enable cooldown, because the Accept header choice is hardwired to Cooldown.Enabled() in internal/handler/npm.go:
accept := npmAbbreviatedCT
if h.proxy.Cooldown != nil && h.proxy.Cooldown.Enabled() {
accept = contentTypeJSON
}
Reproduction
- Deploy the proxy with the default config (no cooldown block)
- Point the upstream at a JFrog Artifactory npm virtual repository
- Request any package metadata:
curl https://<proxy>/npm/lodash
- Proxy logs "failed to fetch npm metadata" error="upstream returned 406", client receives 502
Current workaround
Setting cooldown.default: "1s" enables Cooldown.Enabled() → forces application/json → Artifactory responds correctly. The 1s duration has no practical effect on version filtering since all published versions are older than 1 second.
Proposed fix
Add a dedicated config option to control the npm Accept header independently of cooldown, e.g.:
npm:
full_metadata: true # always use application/json, regardless of cooldown
Or invert the logic: always request application/json from upstream (Artifactory and the public npm registry both support it), and only switch to abbreviated when explicitly opted in. The abbreviated format's main benefit is size — but given the proxy already buffers and caches metadata, the savings may not justify the compatibility cost.
Environment
git-pkgs/proxy v0.6.0
Upstream: JFrog Artifactory npm virtual repository (/artifactory/api/npm//)
Summary
When
cooldownis not configured (the default), the npm handler requests upstream metadata withAccept: application/vnd.npm.install-v1+json(abbreviated packuments). Some upstream registries — specifically JFrog Artifactory npm virtual repositories — return 406 Not Acceptable for this content type. The proxy then logs "failed to fetch npm metadata" error="upstream returned 406" and returns 502 to the client.The only way to force
Accept: application/json(which Artifactory accepts) is to enable cooldown, because the Accept header choice is hardwired to Cooldown.Enabled() ininternal/handler/npm.go:Reproduction
curl https://<proxy>/npm/lodashCurrent workaround
Setting cooldown.default: "1s" enables Cooldown.Enabled() → forces application/json → Artifactory responds correctly. The 1s duration has no practical effect on version filtering since all published versions are older than 1 second.
Proposed fix
Add a dedicated config option to control the npm Accept header independently of cooldown, e.g.:
Or invert the logic: always request application/json from upstream (Artifactory and the public npm registry both support it), and only switch to abbreviated when explicitly opted in. The abbreviated format's main benefit is size — but given the proxy already buffers and caches metadata, the savings may not justify the compatibility cost.
Environment
git-pkgs/proxy v0.6.0
Upstream: JFrog Artifactory npm virtual repository (/artifactory/api/npm//)