iflytek/astron-agent · error

Tenant application credential verification is not…

Error message

Tenant application credential verification is not configured or incomplete

What it means

HttpTenantGatewayAuthClient.verify fails closed when any of the tenant app-verification prerequisites is absent: the verifyAppAuthUrl is not configured, or apiKey/apiSecret are blank. It logs a warning and returns Optional.empty(), so the caller treats the credentials as unverified. No HTTP call is made.

Solutions

  1. Set the tenant verify-app-auth-url configuration property (env var or application.yml) in the active profile.
  2. Ensure the application being verified has a non-empty api_key and api_secret stored.
  3. Confirm the config binds to HttpTenantGatewayAuthClient's @Value/@ConfigurationProperties field (name and profile).
  4. If credentials are legitimately absent, surface a clear 'app not configured' error to the gateway caller instead of silently returning empty.

Example fix

# before
# (property absent)
# after
tenant:
  gateway:
    verify-app-auth-url: http://tenant-service:8080/internal/verify-app-auth
Defensive patterns

Strategy: validation

Validate before calling

// startup readiness check
if (!StringUtils.hasText(props.getVerifyAppAuthUrl())) {
    throw new IllegalStateException("tenant verify-app-auth-url must be configured");
}

Type guard

boolean verifyConfigReady = StringUtils.hasText(verifyAppAuthUrl);
boolean credsPresent = StringUtils.hasText(apiKey) && StringUtils.hasText(apiSecret);

Try / catch

Optional<String> appId = authClient.verify(apiKey, apiSecret);
if (appId.isEmpty()) {
    log.warn("app credentials unverified: config missing or verification rejected");
    return unauthorized();
}

Prevention

When it happens

Trigger: verify(apiKey, apiSecret) called while verifyAppAuthUrl property is missing/blank, or either credential argument is null/empty.

Common situations: Tenant gateway auth not configured in application.yml/env (missing verify-app-auth-url); caller passes empty key or secret from an unconfigured application record; property name typo after refactor; config not loaded in the active Spring profile.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/0a03d154e898e470. Report an issue: GitHub.

Appendix: source

Thrown at console/backend/hub/src/main/java/com/iflytek/astron/console/hub/service/gateway/impl/HttpTenantGatewayAuthClient.java:51

    public HttpTenantGatewayAuthClient(
            @Value("${tenant.verify-app-auth}") String verifyAppAuthUrl,
            @Value("${api.url.apiSecret:}") String tenantInternalKey) {
        this(new OkHttpClient(), verifyAppAuthUrl, tenantInternalKey);
    }

    HttpTenantGatewayAuthClient(
            OkHttpClient httpClient, String verifyAppAuthUrl, String tenantInternalKey) {
        this.httpClient = httpClient;
        this.verifyAppAuthUrl = verifyAppAuthUrl;
        this.tenantInternalKey = tenantInternalKey;
    }

    @Override
    public Optional<String> verify(String apiKey, String apiSecret) {
        if (!StringUtils.hasText(verifyAppAuthUrl)
                || !StringUtils.hasText(apiKey)
                || !StringUtils.hasText(apiSecret)) {
            log.warn("Tenant application credential verification is not configured or incomplete");
            return Optional.empty();
        }
        String configuredInternalKey;
        try {
            configuredInternalKey =
                    TenantInternalApiKey.requireConfigured(tenantInternalKey);
        } catch (IllegalStateException exception) {
            log.warn("Tenant internal authentication is not configured; verification was not sent");
            return Optional.empty();
        }

        JSONObject requestBody = new JSONObject();
        requestBody.put("api_key", apiKey);
        requestBody.put("api_secret", apiSecret);

        Request request = new Request.Builder()
                .url(verifyAppAuthUrl)
                .header(TenantInternalApiKey.HEADER, configuredInternalKey)

View on GitHub (pinned to 5e758547a8)