Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,14 @@ public List<PipelineStatus> getQueuedPipelineStatusInternal(IngestionPipeline in

} catch (ApiException e) {
LOG.error("Failed to check queued pipeline status: {}", e.getResponseBody());
} catch (IllegalArgumentException e) {
// client-java could not deserialize a job returned by a newer Kubernetes
// than its models (see getServiceStatusInternal). Treat as "no queued jobs
// visible" rather than propagating the error to the caller.
LOG.warn(
"Could not deserialize queued job status (client-java lags the cluster's "
+ "Kubernetes version): {}",
e.getMessage());
}

return queuedStatuses;
Expand Down Expand Up @@ -1002,6 +1010,25 @@ protected PipelineServiceClientResponse getServiceStatusInternal() {
e.getResponseBody());
LOG.error(error);
return buildUnhealthyStatus(error);
} catch (IllegalArgumentException e) {
// The list calls above reached the API server successfully (any real
// access/RBAC failure would be an ApiException, handled above). An
// IllegalArgumentException here is thrown by the bundled Kubernetes client
// (client-java) when it cannot DESERIALIZE a pod/job in the response —
// typically because the
// cluster runs a newer Kubernetes than the client models and the response
// carries an unmodeled status field, e.g.:
// IllegalArgumentException: The field `allocatedResources` in the JSON
// string is not defined in the `V1PodStatus` properties
// Cluster access is fine, so report healthy instead of failing the whole
// /services/ingestionPipelines/status endpoint (which blanks the UI).
LOG.warn(
"Kubernetes namespace {} is reachable but a pod/job could not be deserialized "
+ "(client-java models likely lag the cluster's Kubernetes version): {}",
namespace,
e.getMessage());
return buildHealthyStatus(getKubernetesVersion())
.withReason(String.format(K8S_AVAILABLE_FORMAT, namespace, serviceAccount));
Comment on lines +1013 to +1031

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Health check skips verification This branch returns a healthy status as soon as pod or job deserialization throws. Those list calls run before the ConfigMap and Secret reads, so a newer-cluster pod field can jump here before the service account proves it can read the required resources. In that case the status and validation endpoints report Kubernetes as available even when ConfigMap or Secret access is broken. The fallback should not mark the service healthy unless the remaining required checks have still been verified.

Comment on lines +1013 to +1031

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Health Checks Skip Verification This branch returns a healthy status as soon as pod or job deserialization throws. Those list calls run before the ConfigMap and Secret reads, so a newer-cluster pod field can jump here before the service account proves it can read the resources this client needs. The status endpoint can then report Kubernetes as available even when required ConfigMap or Secret access is broken.

}
}

Expand Down Expand Up @@ -1128,6 +1155,16 @@ public Map<String, String> getLastIngestionLogs(
} catch (ApiException e) {
LOG.error("Failed to get logs for pipeline {}: {}", pipelineName, e.getResponseBody());
return Map.of("logs", FAILED_LOGS_MESSAGE + e.getMessage());
} catch (IllegalArgumentException e) {
// client-java could not deserialize a pod returned by a newer Kubernetes
// than its models (see getServiceStatusInternal). Return a graceful message
// instead of propagating the error.
LOG.warn(
"Could not deserialize pod while fetching logs for pipeline {} (client-java lags "
+ "the cluster's Kubernetes version): {}",
pipelineName,
e.getMessage());
return Map.of("logs", FAILED_LOGS_MESSAGE + e.getMessage());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Errors become log content This fallback still returns the deserialization failure under the normal logs payload key. The log response path treats that key as stream content, so users receive a regular log line containing the error message and the stream ends normally. A Kubernetes client parsing failure should be returned in an error-shaped response, not mixed into pipeline output.

Comment on lines +1158 to +1167

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Errors Become Logs This fallback returns the deserialization failure under the normal logs key. The log response path treats that key as stream content, so users receive the Kubernetes parsing error as an ordinary pipeline log line and the stream ends normally. A client-side parsing failure should use an error-shaped response instead of being mixed into pipeline output.

}
Comment thread
greptile-apps[bot] marked this conversation as resolved.
}

Expand Down
Loading