New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DockerFetcher swallows non-JSON errors returned by registries #4672
Comments
@estesp @crosbymichael @dmcgowan PTAL. Happy to work on this (mostly wanted to ask for the motivations for #3173, and if the |
cc @jonjohnsonjr Discussed related aspect of this docker/build-push-action#171 (comment) (although actual error condition/request is different here) |
Well the endpoint does actually return a JSON response for the 429 status code. Here is an example that would be identical to running
|
Yes, the fetcher is looking for an array. |
I opened #4674 with the assumption it would just be an unformatted string, but can update fix decoding the type. |
Thanks @ingshtrom ! Let me copy from our slack chat; Looks like the expected format is; {
"errors": [
{
"code": "<error identifier, see below>",
"message": "<message describing condition>",
"detail": "<unstructured>"
}
]
} So a top-level Reading the spec;
I'm not sure what the expectation is for "invalid formatted JSON" (fallback to print the content verbatim, as a "non-standard" JSON, or something else?) |
So is it a DockerHub bug that it's not sending an array? |
If it is common for other registries to return JSON in that format, its not a big deal to support both formats. In this case, DockerHub should probably use the standard format. I think not returning any detail text from non-JSON responses is the right approach though. |
So the current error returns a |
Yes, for this case it's a bug on Docker Hub side; they're looking into that (also not sure where the format came from on their side; we'll have to check if the same incorrect format is used for other errors as well). IIUC, this particular error message is not generated by the registry itself, but the proxy in front of it handling rate limits, so I guess other registries would not return the same format. That said (as I mentioned above); I'm curious where this particular format originated from, and if there's other occurrences (was it a format returned by v1 registries?) Also curious how the docker daemon was able to convert it into a proper error message (will have to dig into the code for that, but perhaps someone else knows) |
Sure enough, the dist registry client has this:
|
Not sure about that; I think servers returning a plain text error message would be more common (and described by the distribution spec as "valid"), or is that not what you meant? |
I also agree with the plain text approach. For something like 429 specifically the registry may be in a degraded state as it is and serving out plain text instead. |
Looks like there's another bug in the unmarshaller and maybe why I never see error details from containerd. From MarshalJSON: containerd/remotes/docker/errcode.go Lines 219 to 221 in 5184bcc
And UnmarshalJSON: containerd/remotes/docker/errcode.go Lines 256 to 258 in 5184bcc
The dist errcode package specifies the json as |
Also doesn't really matter, because the error "details" are not part of the error string, only the code and the "message". |
Docker Hub is fine. It returns the below now.
|
While DockerHub returns the errors array, the fetcher should support non-JSON errors to return as much information as possible. Fixes containerd#4672.
While DockerHub returns the errors array, the fetcher should support non-JSON errors to return as much information as possible. Fixes containerd#4672. Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
While DockerHub returns the errors array, the fetcher should support non-JSON errors to return as much information as possible. Fixes containerd#4672. Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
While DockerHub returns the errors array, the fetcher should support non-JSON errors to return as much information as possible. Fixes containerd#4672. Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
While DockerHub returns the errors array, the fetcher should support non-JSON errors to return as much information as possible. Fixes containerd#4672. Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
While DockerHub returns the errors array, the fetcher should support non-JSON errors to return as much information as possible. Fixes containerd#4672. Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
While DockerHub returns the errors array, the fetcher should support non-JSON errors to return as much information as possible. Fixes containerd#4672. Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
While DockerHub returns the errors array, the fetcher should support non-JSON errors to return as much information as possible. Fixes containerd#4672. Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
While DockerHub returns the errors array, the fetcher should support non-JSON errors to return as much information as possible. Fixes containerd#4672. Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
While DockerHub returns the errors array, the fetcher should support non-JSON errors to return as much information as possible. Fixes containerd#4672. Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
While DockerHub returns the errors array, the fetcher should support non-JSON errors to return as much information as possible. Fixes containerd#4672. Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
While DockerHub returns the errors array, the fetcher should support non-JSON errors to return as much information as possible. Fixes containerd#4672. Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
Description
Docker Hub has introduced rate-limits, and now returns a
429
status code if those rate limits are reached, with details about the rate limits in the response body (as plain text).However, it looks like the containerd "docker" fetcher code does not return the response body if it's not formatted as JSON.
Steps to reproduce the issue:
When using buildkit (which uses the containerd code to pull images), not details are returned;
Whereas using the "classic" builder, which uses the docker/distribution code returns the error-message returned by the registry;
Same when doing a straight
docker pull
;Describe the results you expected:
I expect the pull code to either;
While a JSON formatted error can be returned, a plain-text body is allowed to be returned as well; looking at the distribution spec; https://github.com/opencontainers/distribution-spec/blob/v1.0.0-rc1/spec.md#error-codes
Digging a bit into the error handling, I see that de1da8b (#3173) may be the culprit. That commit was opened as a follow-up to #3109, which addressed a similar issue as reported here (#3076).
I couldn't find details about #3173. I see that commit removed the
ioutil.ReadAll(resp.Body)
, which may have been the reason (to prevent a DOS where the body would lead to memory exhaustion). The PR review did have this comment; #3173 (comment)So on the bright side, I guess we at least have a way to test server responses.
Any other relevant information:
More of a side-note (probably worth a separate "enhancement" ticket; there may be other omissions in handling of server-responses. I see that "old" docker/distribution code that docker uses is (too) "complicated", but has more specific handling for errors returned; https://github.com/docker/distribution/blob/749f6afb4572201e3c37325d0ffedb6f32be8950/registry/client/errors.go#L41-L84
And the docker code further improves handling by looking if certain request should be retried; https://github.com/moby/moby/blob/ad1b781e44fa1e44b9e654e5078929aec56aed66/distribution/errors.go#L148-L180
The text was updated successfully, but these errors were encountered: