Overview
The Server Sent Events Source Connector connects to an HTTP endpoint that supports Server-Sent Events (SSE), continuously receives events, and writes them to a specified Kafka topic. It is suitable for ingesting service status updates, notification streams, or other real-time data published over a long-lived SSE connection into Kafka for downstream stream processing, storage, or distribution systems. Each SSE event maps to one Kafka record. The record value uses a fixed structure with three string fields:event, id, and data. The data field remains a string; JSON or XML within it is not parsed automatically. The record key is null, and the SSE event ID is not stored as a Kafka Connect offset.
License
Uses Apache License 2.0.Quick Start
Prepare a Connect Cluster, Kafka, and an SSE endpoint that does not require authentication, and confirm network connectivity and access permissions. For preparation and management, see Manage Connector.<sse-endpoint-url> with an SSE endpoint accessible to the Connect Worker, and replace <kafka-topic> with the Kafka topic that receives events. After applying the configuration, check both the Connector and Task status and verify actual events in the target topic. A running Task alone does not mean that the SSE connection has produced data.
Configuration
Kafka Connect Framework
connector.class
The Server Sent Events Source Connector implementation class to load.
- Type:
string - Default: None
- Importance: High
- Valid Values / Notes: Use
com.github.cjmatta.kafka.connect.sse.ServerSentEventsSourceConnector. - Required: Yes
tasks.max
The maximum number of Tasks that Kafka Connect requests the Connector to create.
- Type:
int - Default:
1 - Importance: High
- Valid Values / Notes: Must be at least
1. This Connector always creates only one Task; increasing this value does not increase the number of SSE connections or consumption concurrency.
SSE Connection and Output
sse.uri
The SSE stream address to which the Task connects.
- Type:
string - Default: None
- Importance: High
- Valid Values / Notes: Use an SSE endpoint accessible to every candidate Worker. The Connector does not validate the URI format, protocol, or reachability during configuration parsing.
- Required: Yes
topic
The Kafka topic that receives all SSE events.
- Type:
string - Default: None
- Importance: High
- Valid Values / Notes: One Connector instance can write to only one fixed topic. It does not support configuring a topic list or routing rules based on event content.
- Required: Yes
HTTP Authentication and Request Headers
http.basic.auth
Controls whether the Connector reads the username and password for HTTP Basic Authentication.
- Type:
boolean - Default:
false - Importance: Medium
- Valid Values / Notes: Can be set to
trueorfalse. When enabled, the Task reads thepassword-typed configuration as a string and may fail with a type-conversion error during startup. Even if an Authorization header is constructed, the current implementation does not pass that request builder to the actual SSE handshake. Do not treat this as an available authentication method.
http.basic.auth.username
The username for HTTP Basic Authentication.
- Type:
string - Default:
null - Importance: Medium
- Valid Values / Notes: Read only when
http.basic.auth=true. The Connector does not validate that the value is nonempty or that it is configured together with the password. Because of the Basic Auth implementation limitations, do not rely on this configuration for endpoints that require authentication.
http.basic.auth.password
The password for HTTP Basic Authentication.
- Type:
password - Default:
null - Importance: Medium
- Valid Values / Notes: Read only when
http.basic.auth=true. Enabling Basic Auth and providing a password may cause a type-conversion error when the Task starts. Do not expose real passwords in plaintext configurations, logs, or documentation.
http.header.*
Reads custom HTTP request-header configurations. The name after http.header. is used as the request header name.
- Type:
dynamic-prefix string values - Default:
{} - Importance: Medium
- Valid Values / Notes: For example,
http.header.User-Agentrepresents theUser-Agentrequest header. The Connector does not validate header names or values, and values may contain sensitive credentials. The current implementation adds these headers to a request builder that is not passed toSseEventSource, so do not rely on this configuration for authentication, access control, or User-Agent overrides.
HTTP Client
compression.enabled
Controls the gzip encoding property of the Jersey client.
- Type:
boolean - Default:
true - Importance: Low
- Valid Values / Notes: Can be set to
trueorfalse. When enabled, the Connector sets Jersey’s gzip encoding property, but the explicitly constructedAccept-Encodingheader is not connected to the actual SSE handshake path. Validate compression negotiation and response decompression behavior against the target SSE service.
Connection Rate Limiting
rate.limit.requests.per.second
Controls the minimum interval before the Connector opens or reopens an SSE connection.
- Type:
double - Default:
null - Importance: Low
- Valid Values / Notes: A positive value is used to calculate the wait time between connection-opening requests.
null,0, or a negative value does not enable this wait. It does not limit SSE event throughput and is not a Worker-wide request rate limit.
rate.limit.max.concurrent
Declares the maximum number of concurrent connections.
- Type:
int - Default:
null - Importance: Low
- Valid Values / Notes: Although the current implementation accepts and stores this value, it does not use it to limit connection, Task, or request concurrency. Do not use it as a concurrency control mechanism.
Reconnection Parameters
retry.backoff.initial.ms
Sets the initial wait time for a reconnection triggered by the idle health check and contributes to calculating the SSE client’s own reconnection interval.
- Type:
long - Default:
2000 - Importance: Low
- Valid Values / Notes: The unit is milliseconds. The Connector does not validate that the value is nonnegative. The interval used by the SSE client itself does not exceed
2000milliseconds, while an idle health-check reconnection uses the configured value as the first exponential-backoff wait.
retry.backoff.max.ms
Sets the maximum exponential-backoff wait time for a reconnection triggered by the idle health check.
- Type:
long - Default:
30000 - Importance: Low
- Valid Values / Notes: The unit is milliseconds. The Connector does not validate that the value is nonnegative or require it to be greater than or equal to
retry.backoff.initial.ms. It does not control every reconnection path of the SSE client itself.
retry.max.attempts
Limits the number of idle health-check reconnection attempts managed by the Connector.
- Type:
int - Default:
-1 - Importance: Low
- Valid Values / Notes:
-1means unlimited attempts, and0rejects the first reconnection of this type. Values less than-1are not treated as unlimited. This configuration does not guarantee coverage of asynchronous SSE errors, every HTTP status, or recovery after a Task failure.
Monitoring
What to Monitor
Monitor Kafka Connect health, Connector and Task status, throughput, latency, offset commits, errors, retries, and Worker JVM signals. Also monitor logs related to SSE connection errors and queue growth to prevent heap memory pressure when the source continuously outpaces Kafka. Monitor DLQ activity only when the corresponding error handling is enabled, but do not rely on the DLQ to capture connection and event-processing errors internal to the Connector.Import the Grafana Dashboard
Ensure that Connect metrics are available in a Grafana data source and that the collected labels match the dashboard filters; download the Kafka Connect Dashboard, import the JSON into Grafana, and select the corresponding data source.Limitations
- One Connector instance connects to one SSE URI, writes to one fixed topic, and always creates only one Task. To connect to multiple SSE endpoints, create a separate Connector instance for each endpoint.
- The Connector does not provide event-type filtering or parse
datacontent. SSEdatais always written as a string field in the fixed structure. - The Connector does not store SSE event IDs as Kafka Connect offsets and does not provide persistent deduplication. Task or Worker restarts and reconnections may cause duplicates or omissions; do not claim exactly-once, duplicate-free, omission-free, or unconditional at-least-once delivery.
- SSE events first enter an unbounded in-memory queue, and a single poll has no record-count or byte-size limit. If the source continuously outpaces Kafka, heap memory pressure may occur.
- Basic Auth has a password type-conversion failure path. The Authorization header, custom headers, and explicit
Accept-Encodingheader are added to a request builder that is not passed toSseEventSource. Do not rely on these configurations to access protected endpoints or override the User-Agent. rate.limit.max.concurrentdoes not enforce a concurrency limit.rate.limit.requests.per.secondaffects only the wait before the Connector actively opens a connection; it does not limit event throughput or every internal reconnection performed by the SSE client.- The reconnection parameters cover only specific connection lifecycle paths. They cannot guarantee that every initial connection failure, asynchronous error, or HTTP response is retried and recovered automatically.
- An SSE message without an
eventname may be skipped or emitted withevent=unknown, depending on its position within a batch.
FAQ
The Connector and Task Are Running, but the Target Topic Has No Messages
A successfully started Task does not necessarily mean that the SSE stream is connected and continuously producing events. Confirm thatsse.uri is accessible from the Worker running the Task, that the endpoint returns a valid SSE response, and that it is publishing events with data. Check the Worker logs for connection, protocol, and asynchronous errors, and verify output in the target topic. For endpoints that require Basic Auth or custom request headers, do not assume that the current configuration can complete the handshake. Prefer a controlled endpoint without authentication when isolating the problem.
Duplicate Messages Appear or a Segment of Events Is Missing After a Restart
The Connector does not store a recoverable SSE consumption position or write event IDs to Kafka Connect offsets. Even if the SSE service supportsLast-Event-ID, after a Task or Worker restart the Connector has no persisted event ID from which to resume. Use stable business identifiers for idempotent processing or deduplication downstream, and monitor both duplicates and data gaps during restart windows. Do not rely on offset commits to eliminate this risk.
Increasing tasks.max Still Produces Only One Task
This is the task-allocation boundary of the Connector. It always returns one Task configuration, so increasing tasks.max does not increase the number of SSE connections or throughput. To ingest multiple endpoints, create an independent Connector instance for each endpoint. Validate capacity planning for a single endpoint against the source event rate, Kafka write capacity, and Worker memory.
Worker Memory Usage Keeps Growing
The SSE callback writes events to an unbounded in-memory queue, and the Connector provides neither backpressure nor a batch limit. Check the source event rate, Kafka produce latency, Task errors, and queue-related logs. Reduce the source send rate, restore Kafka write capacity, or separate different endpoints into independent Connector instances, and configure memory and alert thresholds for the Worker.rate.limit.requests.per.second limits only how often connections are opened; it cannot reduce the event rate of an established SSE stream.