microsoft/aspire · error · InvalidOperationException

Qdrant Client is unavailable

Error message

Qdrant Client is unavailable

What it means

AddQdrant registers a health check that needs a QdrantClient instance. If no client was provided or resolvable from the resource's connection string at registration time, the health check factory throws InvalidOperationException('Qdrant Client is unavailable') when it evaluates. This signals that the hosting code could not construct the client needed to probe Qdrant.

Solutions

  1. Ensure the Qdrant resource has a valid connection string (via RunWithConnectionString/callback or a proper reference) before the app starts.
  2. Pass an explicit QdrantClient instance to AddQdrant if you construct one yourself (e.g. with endpoint and API key).
  3. Verify the connection-name used with WithReference matches the resource name so the connection string resolves.
  4. Check that CreateQdrantClient can parse the connection string as an absolute URI or key/value pair with an 'Endpoint' entry.

Example fix

// before
var qdrant = builder.AddQdrant("qdrant");

// after
var qdrant = builder.AddQdrant("qdrant", connectionString: "Endpoint=http://localhost:6334;Key=secret");
Defensive patterns

Strategy: validation

Validate before calling

// Ensure connection info exists before the health check runs
if (string.IsNullOrEmpty(connectionString) && qdrantClient is null)
{
    throw new InvalidOperationException("Provide a QdrantClient or a valid connection string before calling AddQdrant.");
}

Prevention

When it happens

Trigger: Calling AddQdrant (or AddQdrant with an explicit connection string/reference) where neither a QdrantClient argument is passed nor a valid connection string/endpoint can be resolved, so the factory lambda `qdrantClient ?? throw new InvalidOperationException(...)` executes during a health check evaluation.

Common situations: Misconfigured or missing connection string on the Qdrant resource; calling an overload without supplying a client while the resource's connection string is not yet available; typos in the connection-name reference so CreateQdrantClient receives null.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/83bb44d51624cae4. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Qdrant/QdrantBuilderExtensions.cs:66

        var apiKeyParameter = apiKey?.Resource ??
            ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(builder, $"{name}-Key", special: false);
        var qdrant = new QdrantServerResource(name, apiKeyParameter);

        QdrantClient? qdrantClient = null;

        builder.Eventing.Subscribe<ConnectionStringAvailableEvent>(qdrant, async (@event, ct) =>
        {
            var connectionString = await qdrant.ConnectionStringExpression.GetValueAsync(ct).ConfigureAwait(false)
            ?? throw new DistributedApplicationException($"ConnectionStringAvailableEvent was published for the '{qdrant.Name}' resource but the connection string was null.");

            qdrantClient = CreateQdrantClient(connectionString);
        });

        var healthCheckKey = $"{name}_check";
        builder.Services.AddHealthChecks()
          .Add(new HealthCheckRegistration(
              healthCheckKey,
              sp => new QdrantHealthCheck(qdrantClient ?? throw new InvalidOperationException("Qdrant Client is unavailable")),
              failureStatus: default,
              tags: default,
              timeout: default));

        return builder.AddResource(qdrant)
            .WithImage(QdrantContainerImageTags.Image, QdrantContainerImageTags.Tag)
            .WithImageRegistry(QdrantContainerImageTags.Registry)
            .WithIconName("DatabaseSearch")
            .WithHttpEndpoint(port: grpcPort, targetPort: QdrantPortGrpc, name: QdrantServerResource.PrimaryEndpointName)
            .WithEndpoint(QdrantServerResource.PrimaryEndpointName, endpoint =>
            {
                endpoint.Transport = "http2";
            })
            .WithHttpEndpoint(port: httpPort, targetPort: QdrantPortHttp, name: QdrantServerResource.HttpEndpointName)
            .WithEnvironment(context =>
            {
                context.EnvironmentVariables[ApiKeyEnvVarName] = qdrant.ApiKeyParameter;

View on GitHub (pinned to 25830f84bd)