grpc/grpc-java · error · VerifyException

key ' ' missing in

Error message

key '%s' missing in '%s'

What it means

Each service-config choice from DNS must contain the `serviceConfig` key. In maybeChooseServiceConfig, after selecting a choice map, if the `serviceConfig` key is absent, the resolver throws a VerifyException describing which choice failed - the selection cannot produce a usable service config.

Solutions

  1. Publish the choice as an object containing a non-null `serviceConfig` key, e.g. {"clientLanguage":..., "serviceConfig":{...}}.
  2. Validate DNS TXT service-config choices against the gRPC service-config-choice schema before publishing.
  3. Remove malformed choices so the resolver can pick a valid one.

Example fix

// before (TXT record)
grpc_config=[{"clientLanguage":"java"}]
// after (TXT record)
grpc_config=[{"clientLanguage":"java","serviceConfig":{...}}]
Defensive patterns

Strategy: validation

Validate before calling

Map<String, ?> choice = JsonUtil.getObject(raw, ...);
if (choice == null || !choice.containsKey("serviceConfig")) {
  throw new IllegalArgumentException("service config choice lacks 'serviceConfig' key");
}

Try / catch

try {
  sc = maybeChooseServiceConfig(choice);
} catch (VerifyException e) {
  // skip malformed choice, use default service config
}

Prevention

When it happens

Trigger: A DNS TXT `grpc_config` choice object that lacks the `serviceConfig` key (or has it misspelled / null), so JsonUtil.getObject returns null during service-config selection.

Common situations: Wrong service-config schema published in DNS (older or hand-written choices); fields renamed after a spec change; partial records produced by automation that failed mid-write.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/291bf7b17f00c4b7. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/io/grpc/internal/DnsNameResolver.java:512

      }
    }
    List<String> clientHostnames = getHostnamesFromChoice(choice);
    if (clientHostnames != null && !clientHostnames.isEmpty()) {
      boolean hostnamePresent = false;
      for (String clientHostname : clientHostnames) {
        if (clientHostname.equals(hostname)) {
          hostnamePresent = true;
          break;
        }
      }
      if (!hostnamePresent) {
        return null;
      }
    }
    Map<String, ?> sc =
        JsonUtil.getObject(choice, SERVICE_CONFIG_CHOICE_SERVICE_CONFIG_KEY);
    if (sc == null) {
      throw new VerifyException(String.format(
          "key '%s' missing in '%s'", choice, SERVICE_CONFIG_CHOICE_SERVICE_CONFIG_KEY));
    }
    return sc;
  }

  /**
   * Describes a parsed SRV record.
   */
  @VisibleForTesting
  public static final class SrvRecord {
    public final String host;
    public final int port;

    public SrvRecord(String host, int port) {
      this.host = host;
      this.port = port;
    }

View on GitHub (pinned to 64daddc1f3)