Summary
The client-server version compatibility check performed in QdrantGrpcClient.Builder.build() is issued without the API key when credentials are configured via withApiKey(...). Against an auth-required server (e.g. Qdrant Cloud) the health check is rejected, and the client logs on every startup:
Failed to obtain server version. Unable to check client-server compatibility. Set checkCompatibility=false to skip version check.
This is a regression of #96, which was fixed in #97 but later undone.
Affected versions
1.18.0 through 1.18.2 (and current master). 1.16.2 and 1.17.0 are not affected.
Root cause
withApiKey(...) no longer sets callCredentials. Since the custom-headers refactor (49e4826, first released in 1.18.0) it only stores the raw apiKey, and the MetadataCredentials are constructed in build() after the compatibility check runs:
public QdrantGrpcClient build() {
if (checkCompatibility) {
String clientVersion = Builder.class.getPackage().getImplementationVersion();
checkVersionsCompatibility(clientVersion); // (1) runs first
}
CallCredentials credentials = this.callCredentials;
if (credentials == null && (apiKey != null || headers != null)) {
credentials = new MetadataCredentials(apiKey, headers); // (2) built afterwards
}
...
}
private void checkVersionsCompatibility(String clientVersion) {
...
QdrantGrpc.newBlockingStub(this.channel)
.withCallCredentials(this.callCredentials) // null when only withApiKey() was used
.healthCheck(...)
...
}
The #97 fix worked only because, at the time, withApiKey() set this.callCredentials = new ApiKeyCredentials(apiKey) directly. The custom-headers refactor changed that to defer credential construction, silently re-breaking the check (there was no regression test guarding it).
Reproduction
Build a client against an API-key-protected server (Qdrant Cloud) with the default checkCompatibility=true:
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("xyz.cloud.qdrant.io", 6334, true)
.withApiKey("<api-key>")
.build());
The warning is logged at build time. (The resulting client works for normal calls — only the build-time version check is unauthenticated.) The underlying error is PERMISSION_DENIED: HTTP status code 403.
Expected
The compatibility check should use the same credentials the client will use, including the API key provided via withApiKey(...).
Fix
PR incoming: resolve the effective credentials before running the check and pass them into it, plus a regression test. Happy to adjust to your preferences.
Summary
The client-server version compatibility check performed in
QdrantGrpcClient.Builder.build()is issued without the API key when credentials are configured viawithApiKey(...). Against an auth-required server (e.g. Qdrant Cloud) the health check is rejected, and the client logs on every startup:This is a regression of #96, which was fixed in #97 but later undone.
Affected versions
1.18.0through1.18.2(and currentmaster).1.16.2and1.17.0are not affected.Root cause
withApiKey(...)no longer setscallCredentials. Since the custom-headers refactor (49e4826, first released in1.18.0) it only stores the rawapiKey, and theMetadataCredentialsare constructed inbuild()after the compatibility check runs:The #97 fix worked only because, at the time,
withApiKey()setthis.callCredentials = new ApiKeyCredentials(apiKey)directly. The custom-headers refactor changed that to defer credential construction, silently re-breaking the check (there was no regression test guarding it).Reproduction
Build a client against an API-key-protected server (Qdrant Cloud) with the default
checkCompatibility=true:The warning is logged at build time. (The resulting client works for normal calls — only the build-time version check is unauthenticated.) The underlying error is
PERMISSION_DENIED: HTTP status code 403.Expected
The compatibility check should use the same credentials the client will use, including the API key provided via
withApiKey(...).Fix
PR incoming: resolve the effective credentials before running the check and pass them into it, plus a regression test. Happy to adjust to your preferences.