Skip to content

Errors

Every refusal is a sentinel created with errors.NewSentinel, so it survives a process boundary and can be counted by kind. Match with errors.Is.

Registry

ErrImmutable

An identifier was republished with different bytes, a different language, or a different root. This is the property the whole registry rests on — see Why a published URN cannot change.

409 Conflict over HTTP. The fix is to publish the next version, not to force this one.

Republishing identical bytes is not an error, so a deployment that registers its schemas on every start is idempotent.

ErrNotFound

Nothing is published under that identifier. 404 over HTTP.

Worth distinguishing from an unreachable registry, which is why the client maps a 404 to this and everything else to a transport error: the first is a fact, the second is an outage.

ErrUnsupportedCompatibility

A caller asked for a compatibility guarantee this release cannot provide. Only CompatibilityNone is accepted. 400 over HTTP.

Being told is the point. See The compatibility-shaped gap.

ErrUnknownLanguage

The registry has no checker registered for the schema's language, or a Guard has no validator for it. The language is a real one; nothing was wired for it.

At publish time it is a wiring mistake, found at the first publication rather than as a schema that silently skips a check somebody believes is running. At validation time it fails open and is counted.

ErrEmpty

A schema with no bytes. An empty schema validates everything, which is indistinguishable from validating nothing.

ErrInvalidPayload

A payload does not conform to the schema it names. This is the one failure that is not open — failing open on a schema that resolved and did not match would make the whole exercise decorative.

It means the producer is at fault, and only that. A schema that will not compile is ErrSchemaUnusable.

ErrSchemaUnusable

The schema resolved but cannot be used to validate anything: a JSON Schema that will not compile, a protobuf schema that is not a descriptor set, or one that does not name its root message.

A Guard fails OPEN on this and counts it, because it is our mistake rather than the producer's. Reporting it as ErrInvalidPayload — which is what an earlier version did — means one mis-published schema rejects every message on a topic while the fail-open counter reads zero and the alert says the consumer is healthy. That is the outage the fail-open design exists to prevent, arriving through the failure most likely to actually happen.

ErrInvalidLanguage

A schema names a language this module does not define. Refused by Publish and by Embed, 400 over HTTP.

Distinct from ErrUnknownLanguage, which is about wiring: this one is about the value itself. A one-character typo in a Language constant would otherwise produce a service that publishes cleanly, starts cleanly, and validates nothing for the life of the deployment — signalled only by a counter that looks identical to a registry outage.

Protobuf

protobuf.ErrNoRoot

A protobuf schema did not name its root message. See Schema languages.

Serving

serve.ErrNoAuthentication

A publisher was mounted with no middleware in front of it. Pass serve.Authenticate, or serve.AllowAnonymousPublishing() if that is genuinely intended — the second exists so the decision is written down at the call site rather than reached by forgetting to pass anything.

URN

Listed in go/cloudevents/urn alongside the rules they enforce. A dataschema that is not one of ours is urn.ErrNotAURN, and a Guard treats that like any other unresolvable identifier: fail open, and count it.