tailscale/tailscale · error

error marshalling updated owner references: %w

Error message

error marshalling updated owner references: %w

What it means

Defensive error if json.Marshal of the updated ownerAnnotationValue (original refs plus the appended {OperatorID} ref) fails. The struct contains only strings and a pointer-to-struct Resource field, so encoding/json cannot realistically fail. Practically unreachable; surfaced only to satisfy the error contract.

Source

Thrown at cmd/k8s-operator/ingress-for-pg.go:929

	}

	o, err := parseOwnerAnnotation(svc)
	if err != nil {
		return nil, err
	}
	if o == nil || len(o.OwnerRefs) == 0 {
		return nil, fmt.Errorf("Tailscale Service %s exists, but does not contain owner annotation with owner references; not proceeding as this is likely a resource created by something other than the Tailscale Kubernetes operator", svc.Name)
	}
	if slices.Contains(o.OwnerRefs, ref) { // up to date
		return svc.Annotations, nil
	}
	if o.OwnerRefs[0].Resource != nil {
		return nil, fmt.Errorf("Tailscale Service %s is owned by another resource: %#v; cannot be reused for an Ingress", svc.Name, o.OwnerRefs[0].Resource)
	}
	o.OwnerRefs = append(o.OwnerRefs, ref)
	json, err := json.Marshal(o)
	if err != nil {
		return nil, fmt.Errorf("error marshalling updated owner references: %w", err)
	}

	newAnnots := make(map[string]string, len(svc.Annotations)+1)
	maps.Copy(newAnnots, svc.Annotations)
	newAnnots[ownerAnnotation] = string(json)
	return newAnnots, nil
}

// parseOwnerAnnotation returns nil if no valid owner found.
func parseOwnerAnnotation(tsSvc *tailscale.VIPService) (*ownerAnnotationValue, error) {
	if tsSvc == nil {
		return nil, nil
	}

	if tsSvc.Annotations == nil || tsSvc.Annotations[ownerAnnotation] == "" {
		return nil, nil
	}
	o := &ownerAnnotationValue{}

View on GitHub (pinned to cfe32b8be6)

Solutions

  1. Treat as an upstream bug if reproducible and report it with the wrapped error
  2. Check custom builds for modifications to OwnerRef/ownerAnnotationValue types
Defensive patterns

Strategy: try-catch

Try / catch

data, err := json.Marshal(o)
if err != nil {
    // unreachable for this struct; fail loudly and report upstream
    return nil, fmt.Errorf("error marshalling updated owner references: %w", err)
}

Prevention

When it happens

Trigger: ownerAnnotations() after o.OwnerRefs = append(o.OwnerRefs, ref) — no realistic trigger; marshalling a slice of string-bearing structs.

Common situations: Not observed in practice; would require memory corruption or a fork adding unmarshalable types.

Related errors


AI-assisted analysis of tailscale/tailscale@cfe32b8be6 (2026-08-15). Data as JSON: /api/errors/53b5627f74feb33b. Report an issue: GitHub.