kubernetes/kops · error

discoveryService URL must be specified

Error message

discoveryService URL must be specified

What it means

When ServiceAccountIssuerDiscovery.DiscoveryService is set, its URL field is used verbatim as the service account issuer/discovery URL. If the URL is empty, kOps cannot construct the issuer and returns this validation error.

Source

Thrown at pkg/model/components/discovery.go:83

				serviceAccountIssuer, err = base.GetHTTPsUrl()
				if err != nil {
					return err
				}
			case *vfs.MemFSPath:
				if !base.IsClusterReadable() {
					// If this _is_ a test, we should call MarkClusterReadable
					return fmt.Errorf("locationStore=%q is only supported in tests", store)
				}
				serviceAccountIssuer = strings.Replace(base.Path(), "memfs://", "https://", 1)
			default:
				return fmt.Errorf("locationStore=%q is of unexpected type %T", store, base)
			}
		} else if said != nil && said.DiscoveryService != nil {
			discoveryService := said.DiscoveryService

			serviceAccountIssuer = discoveryService.URL
			if serviceAccountIssuer == "" {
				return fmt.Errorf("discoveryService URL must be specified")
			}
		} else {
			if supportsPublicJWKS(clusterSpec) && clusterSpec.API.PublicName != "" {
				serviceAccountIssuer = "https://" + clusterSpec.API.PublicName
			} else {
				serviceAccountIssuer = "https://api.internal." + b.ClusterName
			}
		}
		kubeAPIServer.ServiceAccountIssuer = &serviceAccountIssuer
	}
	kubeAPIServer.ServiceAccountJWKSURI = new(*kubeAPIServer.ServiceAccountIssuer + "/openid/v1/jwks")
	// We set apiserver ServiceAccountKey and ServiceAccountSigningKeyFile in nodeup

	return nil
}

func supportsPublicJWKS(clusterSpec *kops.ClusterSpec) bool {
	if !fi.ValueOf(clusterSpec.KubeAPIServer.AnonymousAuth) {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Set discoveryService.url to the HTTPS URL serving OIDC discovery (/.well-known/openid-configuration and jwks)
  2. Remove the empty discoveryService block so the default issuer logic is used instead
  3. Validate the cluster spec with kops before applying

Example fix

// before
serviceAccountIssuerDiscovery:
  discoveryService: {}
// after
serviceAccountIssuerDiscovery:
  discoveryService:
    url: "https://discovery.example.com"
Defensive patterns

Strategy: validation

Validate before calling

if said := spec.ServiceAccountIssuerDiscovery; said != nil && said.DiscoveryService != nil && said.DiscoveryService.URL == "" {
    return fmt.Errorf("discoveryService.url is required when discoveryService is set")
}

Type guard

null

Try / catch

if err := buildOptions(); err != nil {
    if strings.Contains(err.Error(), "discoveryService URL must be specified") {
        // populate discoveryService.url in the spec
    }
    return err
}

Prevention

When it happens

Trigger: Cluster spec defines serviceAccountIssuerDiscovery.discoveryService but leaves discoveryService.url unset (empty string) during BuildOptions.

Common situations: Partial YAML: discoveryService key added without url; templating variable that expanded to empty; copy-paste of a sample config missing the url field.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/20e338a815c7dd0d. Report an issue: GitHub.