apache/druid · error · ParseException

Failed to fetch Avro schema id[%s] from registry. Error code

Error message

Failed to fetch Avro schema id[%s] from registry. Error code[%s] and message[%s].

What it means

Catch-all thrown when RestClientException with an error code other than 401 occurs while fetching an Avro schema from the Confluent schema registry. The registry returned an HTTP error; the code and message from the client library are embedded in the ParseException.

Source

Thrown at extensions-core/avro-extensions/src/main/java/org/apache/druid/data/input/avro/SchemaRegistryBasedAvroBytesDecoder.java:162

          null,
          ex1,
          "Failed to fetch Avro schema id[%s] from registry. Check if the schema exists in the registry. Otherwise it"
          + " could mean that there is malformed data in the stream or data that doesn't conform to the schema"
          + " specified.",
          id
      );
    }
    catch (RestClientException ex2) {
      if (ex2.getErrorCode() == 401) {
        throw new ParseException(
            null,
            ex2,
            "Failed to authenticate to schema registry for Avro schema id[%s]. Please check your credentials.",
            id
        );
      }
      // For all other errors, just include the code and message received from the library.
      throw new ParseException(
          null,
          ex2,
          "Failed to fetch Avro schema id[%s] from registry. Error code[%s] and message[%s].",
          id,
          ex2.getErrorCode(),
          ex2.getMessage()
      );
    }
    if (schema == null) {
      throw new ParseException(null, "No Avro schema id[%s] in registry", id);
    }
    DatumReader<GenericRecord> reader = new GenericDatumReader<>(schema);
    try {
      return reader.read(null, DecoderFactory.get().binaryDecoder(bytes.array(), offset, length, null));
    }
    catch (Exception e) {
      throw new ParseException(null, e, "Failed to decode Avro message for schema id[%s]", id);
    }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Read the embedded error code: 404 means the id is missing from the registry — verify or re-register it; 429 means back off/reduce polling; 5xx means retry after registry recovers
  2. Verify the schema registry URL and reachability from Druid
  3. Check registry server logs for the correlated error
  4. Add retries/alerting for transient registry unavailability

Example fix

null
Defensive patterns

Strategy: retry

Validate before calling

// preflight registry status
curl -f http://schema-registry:8081/status > /dev/null && echo OK || echo REGISTRY_DOWN

Try / catch

Retryer<GenericRecord> retryer = RetryerBuilder.<GenericRecord>newBuilder()
    .retryIfException(e -> e instanceof ParseException
        && e.getMessage().contains("Error code"))
    .withWaitStrategy(WaitStrategies.exponentialWait(500, 30, TimeUnit.SECONDS))
    .withStopStrategy(StopStrategies.stopAfterDelay(2, TimeUnit.MINUTES))
    .build();

Prevention

When it happens

Trigger: parse(ByteBuffer bytes) calls registry.getSchemaById(id) and the registry responds with an HTTP error other than 401: 404 (unknown id), 403 (forbidden), 429 (rate limited), 5xx (registry outage), or connectivity errors surfaced as RestClientException.

Common situations: Schema deleted from registry (404); Confluent Cloud plan limits hit (429); registry under load or restarting (5xx); misconfigured registry URL hitting the wrong endpoint (HTML 404 pages).

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/c9c5f62e6c32a335. Report an issue: GitHub.