docker/cli · error
invalid named reference bytes
Error message
invalid named reference bytes: %s: %w
What it means
Returned by SerializableNamed.UnmarshalJSON (types.go:144) when the JSON bytes cannot be unmarshaled into a plain string. SerializableNamed wraps a reference.Named and expects its JSON representation to be a quoted string (the image reference), so any non-string JSON (object, number, array, malformed bytes) fails json.Unmarshal and is wrapped here. The raw bytes are printed for diagnosis.
Solutions
- Validate the JSON before unmarshaling: ensure the Ref field is a JSON string.
- Delete the malformed cached manifest and re-fetch it from the registry.
- If you control serialization, always emit Ref as the string form of the reference (MarshalJSON does json.Marshal(s.String())).
- Use json.Decoder with DisallowUnknownFields during development to catch schema drift early.
Example fix
// before: unmarshaling trust-unchecked bytes
json.Unmarshal(data, &img)
// after: validate Ref is a string first
var probe map[string]json.RawMessage
_ = json.Unmarshal(data, &probe)
if v, ok := probe["Ref"]; ok && len(v) > 0 && v[0] != '"' {
return fmt.Errorf("Ref must be a JSON string, got %s", v)
} Defensive patterns
Strategy: validation
Validate before calling
// Validate the Ref field is a JSON string before unmarshaling into ImageManifest
var probe map[string]json.RawMessage
if err := json.Unmarshal(data, &probe); err != nil {
return err
}
if v, ok := probe["Ref"]; ok && (len(v) == 0 || v[0] != '"') {
return fmt.Errorf("Ref must be a JSON string, got %s", string(v))
} Try / catch
// Catch the unmarshal error and purge corrupt cache
if err := json.Unmarshal(data, &im); err != nil {
if strings.Contains(err.Error(), "invalid named reference bytes") {
_ = os.Remove(filename) // drop corrupt manifest cache
}
return err
} Prevention
- Treat ~/.docker/manifests as opaque; don't edit by hand.
- When serializing SerializableNamed, rely on MarshalJSON (emits a string).
- Add schema validation in CI for any tool that writes these files.
When it happens
Trigger: Deserializing an ImageManifest from JSON whose "Ref" field is not a JSON string — e.g. it is a nested object, null, a bare number, or the file is truncated/corrupted. Also triggered by a version mismatch where an older/newer format serialized Ref differently than a plain string.
Common situations: Hand-editing a cached manifest file and putting an object where a string is expected, a corrupt ~/.docker/manifests entry, or a tool that emits ImageManifest JSON with a non-string Ref representation.
Related errors
- refusing to amend an existing manifest list with no --amend…
- annotate: error parsing name for manifest list
- annotate: error parsing name for manifest
- manifest entry for image has unsupported os/arch combination
- error parsing name for manifest list
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/18a111c0c58daa27.
Report an issue: GitHub.
Appendix: source
Thrown at cli/manifest/types/types.go:144
return ImageManifest{
Ref: &SerializableNamed{Named: ref},
Descriptor: desc,
Raw: raw,
OCIManifest: manifest,
}
}
// SerializableNamed is a reference.Named that can be serialized and deserialized
// from JSON
type SerializableNamed struct {
reference.Named
}
// UnmarshalJSON loads the Named reference from JSON bytes
func (s *SerializableNamed) UnmarshalJSON(b []byte) error {
var raw string
if err := json.Unmarshal(b, &raw); err != nil {
return fmt.Errorf("invalid named reference bytes: %s: %w", b, err)
}
var err error
s.Named, err = reference.ParseNamed(raw)
return err
}
// MarshalJSON returns the JSON bytes representation
func (s *SerializableNamed) MarshalJSON() ([]byte, error) {
return json.Marshal(s.String())
}
View on GitHub (pinned to 4f84911bfe)