cilium/cilium · error
AddrCluster.UnmarshalJSON: bad address
Error message
AddrCluster.UnmarshalJSON: bad address
What it means
AddrCluster is Cilium's cluster-aware address type holding an IP plus optional ClusterID, serialized as "<addr>@<clusterID>" (e.g. "1.2.3.4@1"). UnmarshalJSON returns errUnmarshalBadAddress when the JSON value is not a quoted string of the expected form — e.g. unquoted input, empty string content, or missing surrounding quotes. The package then delegates to ParseAddrCluster, which yields a more specific parse error for malformed IP/clusterID content.
Source
Thrown at pkg/clustermesh/types/addressing.go:48
// (e.g. network endpoint has a unique IP address). We can consider
// this as a special case that ClusterID "doesn't matter". ClusterID
// 0 is reserved for indicating that.
//
// AddrCluster is a type that holds a pair of IP and ClusterID.
// We should use this type as much as possible when we implement
// IP + Cluster addressing. We should avoid managing IP and ClusterID
// separately. Otherwise, it is very hard for code readers to see
// where we are using cluster-aware addressing.
type AddrCluster struct {
addr netip.Addr
clusterID uint32
}
const AddrClusterLen = 20
var (
errUnmarshalBadAddress = errors.New("AddrCluster.UnmarshalJSON: bad address")
errMarshalInvalidAddress = errors.New("AddrCluster.MarshalJSON: invalid address")
jsonZeroAddress = []byte("\"\"")
)
// MarshalJSON marshals the address as a string in the form
// <addr>@<clusterID>, e.g. "1.2.3.4@1"
func (a *AddrCluster) MarshalJSON() ([]byte, error) {
if !a.addr.IsValid() {
if a.clusterID != 0 {
return nil, errMarshalInvalidAddress
}
// AddrCluster{} is the zero value. Preserve this across the
// marshalling by returning an empty string.
return jsonZeroAddress, nil
}
View on GitHub (pinned to ac7b90affa)
Solutions
- Wrap the address value in double quotes in the JSON, in the form "<ip>@<clusterID>" or a bare quoted IP like "1.2.3.4"
- Ensure the value is not the empty string "" — omit the field or use the zero address representation "" only for AddrCluster{}
- Validate with types.ParseAddrCluster(s) before marshaling the JSON to get a precise parse error
- Check the JSON producer: a templating/script step may be dropping the quotes
Example fix
// before
{"addresses": [1.2.3.4@1]}
// after
{"addresses": ["1.2.3.4@1"]} Defensive patterns
Strategy: validation
Validate before calling
func validAddrClusterJSON(b []byte) bool {
return len(b) > 2 && b[0] == '"' && b[len(b)-1] == '"'
}
// or pre-validate the string form:
if _, err := types.ParseAddrCluster(s); err != nil { /* fix before encoding */ } Type guard
func isJSONString(data []byte) bool {
return len(data) >= 2 && data[0] == '"' && data[len(data)-1] == '"'
} Try / catch
var ac types.AddrCluster
if err := json.Unmarshal(data, &ac); err != nil {
if errors.Is(err, types.ErrUnmarshalBadAddress) { // or strings.Contains
log.Warnf("skipping bad address payload %q", data)
return nil // or surface a remediation hint
}
return err
} Prevention
- Always emit addresses as quoted strings "<ip>@<id>"; never rely on tools that drop JSON quotes
- Unit-test JSON round-trips of AddrCluster values
- Use ParseAddrCluster to validate address strings at config load time
When it happens
Trigger: Calling json.Unmarshal (directly or via a struct containing an AddrCluster field) with a JSON value that is not a double-quoted string: a number, an object, or a bare token; or a quoted string of length 0 (""). Strings with content go to ParseAddrCluster, so only empty/non-string JSON triggers this exact error.
Common situations: Hand-editing cluster config/StateStore JSON where an address was written unquoted (e.g. 1.2.3.4@1 without quotes); tools emitting a number instead of a string for an IP field; passing an empty string "" for an address that should have been omitted.
Related errors
- AddrCluster.MarshalJSON: invalid address
- cluster is unset
- namespace is unset
- name is unset
- address type is invalid
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/76cc29d05414237c.
Report an issue: GitHub.