# Capabilities (/connectors/gcp-pub-sub/reference/capabilities)



This reference defines exactly what the embedded KubeMQ Pub/Sub connector **supports**, what it
**accepts-and-ignores**, and what it **rejects**. The connector implements the real Pub/Sub v1
gRPC services — **38 RPCs** total — so unmodified Google client libraries and `gcloud pubsub` talk
to KubeMQ exactly as they would to Google's local emulator. Use it to decide which Pub/Sub SDK
calls are safe to rely on and which ones are refused.

Milestone tags below: **M1** core drop-in · **M2** advanced delivery · **M3** full parity.

## The 38-RPC matrix [#the-38-rpc-matrix]

| Service                          | Count                |
| -------------------------------- | -------------------- |
| `google.pubsub.v1.Publisher`     | 9                    |
| `google.pubsub.v1.Subscriber`    | 16                   |
| `google.pubsub.v1.SchemaService` | 10                   |
| `google.iam.v1.IAMPolicy`        | 3 (permissive stubs) |
| **Total**                        | **38**               |

## Publisher (9) [#publisher-9]

| # | RPC                      | M  | Notes                                                                                                                                                                               |
| - | ------------------------ | -- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | `CreateTopic`            | M1 | Validates the name; `kms_key_name` accepted-and-ignored; ingestion configs rejected (`INVALID_ARGUMENT`); retention clamped to the broker ceiling. Backing log `gcp.{t}`            |
| 2 | `GetTopic`               | M1 | Returns the &#x2A;*requested (un-clamped)** retention                                                                                                                               |
| 3 | `ListTopics`             | M1 | Opaque page token                                                                                                                                                                   |
| 4 | `DeleteTopic`            | M1 | **Tombstone** — the record is retained so existing subscriptions survive; re-creating the topic reuses the log                                                                      |
| 5 | `Publish`                | M1 | Batch (≤ 1000); assigns id + publish-time; writes the topic log once, then fans out one queue copy per subscription (applying each sub's filter). M3 adds schema enforce-on-publish |
| 6 | `ListTopicSubscriptions` | M1 |                                                                                                                                                                                     |
| 7 | `UpdateTopic`            | M2 | FieldMask over `labels`, `message_retention_duration`, `schema_settings`                                                                                                            |
| 8 | `ListTopicSnapshots`     | M3 |                                                                                                                                                                                     |
| 9 | `DetachSubscription`     | M3 | Marks detached, drops backlog + leases; the subscription stays re-fillable by `Seek`                                                                                                |

## Subscriber (16) [#subscriber-16]

| #  | RPC                  | M  | Notes                                                                                                                                                                                   |
| -- | -------------------- | -- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1  | `CreateSubscription` | M1 | Binds to a topic; queue `gcp.sub.{s}` created lazily. Export subscriptions (BigQuery/Cloud Storage/Bigtable) and ingestion are rejected. Filter compiled at create-time (**immutable**) |
| 2  | `GetSubscription`    | M1 | Returns the requested (un-clamped) retention                                                                                                                                            |
| 3  | `ListSubscriptions`  | M1 |                                                                                                                                                                                         |
| 4  | `DeleteSubscription` | M1 | Drops backlog + leases                                                                                                                                                                  |
| 5  | `UpdateSubscription` | M2 | FieldMask over ack deadline / retention / DLQ / retry / push / exactly-once / labels. `name` and `filter` are **immutable**                                                             |
| 6  | `Pull`               | M1 | `max_messages ≤ 1000`; a detached subscription → `FAILED_PRECONDITION`                                                                                                                  |
| 7  | `Acknowledge`        | M1 | Decodes `ack_id` → acks the broker sequence. Exactly-once subs return a status for invalid/expired ids (below)                                                                          |
| 8  | `ModifyAckDeadline`  | M1 | `0` = immediate nack/redeliver; `>0` = extend (10..600 s)                                                                                                                               |
| 9  | `StreamingPull`      | M1 | Bidirectional; per-stream flow control; exactly-once confirmations; periodic server-initiated close every `StreamCloseSeconds`                                                          |
| 10 | `ModifyPushConfig`   | M2 | Switch pull ↔ push; an empty config returns to pull                                                                                                                                     |
| 11 | `Seek`               | M3 | To a timestamp or a snapshot; replays the topic log into the subscription queue, bounded by `MaxSeekReplay`                                                                             |
| 12 | `CreateSnapshot`     | M3 | Cursor snapshot, 7-day default expiry                                                                                                                                                   |
| 13 | `GetSnapshot`        | M3 |                                                                                                                                                                                         |
| 14 | `ListSnapshots`      | M3 |                                                                                                                                                                                         |
| 15 | `UpdateSnapshot`     | M3 | May change `labels` and `expire_time`                                                                                                                                                   |
| 16 | `DeleteSnapshot`     | M3 |                                                                                                                                                                                         |

<Callout type="info">
  The 250 ms lease sweeper, retry backoff, dead-letter republish, and per-key ordering cursor are
  connector-internal mechanics behind these RPCs — see
  [Subscribing](/connectors/gcp-pub-sub/how-to/subscribing) and
  [Reliability](/connectors/gcp-pub-sub/how-to/reliability).
</Callout>

## SchemaService (10, M3) [#schemaservice-10-m3]

`CreateSchema`, `GetSchema` (BASIC/FULL), `ListSchemas`, `ListSchemaRevisions`, `CommitSchema`,
`RollbackSchema`, `DeleteSchemaRevision` (keeps ≥ 1), `DeleteSchema`, `ValidateSchema`,
`ValidateMessage` — over **Avro** and **Protobuf** definitions, each with server-assigned revision
ids and full revision history. A definition that fails to parse → `INVALID_ARGUMENT`; definitions
are capped at **300 KB**. See [Schema Validation](/connectors/gcp-pub-sub/how-to/schema-validation).

## IAMPolicy (3, M2) [#iampolicy-3-m2]

`GetIamPolicy` returns an empty `Policy{Version: 3}`; `SetIamPolicy` and `TestIamPermissions`
**echo** the request. These are **permissive stubs** — there is no IAM enforcement (emulator
parity). The connector runs with **no authentication**.

## Feature support [#feature-support]

| Feature                             | Supported?              | Notes                                                                                                    |
| ----------------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------- |
| Basic publish / pull / ack          | ●                       | M1 core drop-in                                                                                          |
| Batch publish (≤ 1000)              | ●                       | Atomic — the whole batch is validated before anything is enqueued                                        |
| StreamingPull + flow control        | ●                       | Per-stream `max_outstanding_messages` / `_bytes`; `≤ 0` = unlimited (capped by `MaxOutstandingMessages`) |
| Ordering keys                       | ●                       | `enable_message_ordering`; at most one in flight per key, in-order redelivery                            |
| Attribute filtering                 | ●                       | CEL-**subset**, attributes-only, ≤ 256 chars, immutable, applied at fan-out                              |
| Dead-letter topic                   | ●                       | `dead_letter_topic` + `max_delivery_attempts` (5..100)                                                   |
| Push delivery                       | ●                       | Wrapped JSON envelope or `no_wrapper`; optional OIDC Bearer; HTTPS (HTTP only for localhost)             |
| Exactly-once delivery               | ● &#x2A;*(node-local)** | `enable_exactly_once_delivery`; an `ack_id` is valid only on the node that minted it                     |
| Seek to timestamp / snapshot        | ●                       | Replays the topic log; a pre-window timestamp **clamps** to the earliest retained message                |
| Snapshots                           | ●                       | 7-day default expiry, swept hourly                                                                       |
| Schema validation (Avro / Protobuf) | ●                       | Enforce-on-publish; whole batch rejected on the first non-conforming message                             |
| Cross-protocol interop              | ●                       | Pub/Sub publish ⇄ native KubeMQ consume on Events Store `gcp.{t}`                                        |
| IAM enforcement                     | ○                       | Permissive stubs only; no enforcement                                                                    |

## Accepted-and-ignored / rejected [#accepted-and-ignored--rejected]

These are documented non-goals. They are **never** used as working examples, and most are actively
rejected by the connector with the [error code](/connectors/gcp-pub-sub/reference/error-codes)
shown:

| Operation / field                                          | Behavior                                                                                     |
| ---------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `kms_key_name` (on `CreateTopic`)                          | **accepted and ignored** — no KMS in emulator mode                                           |
| Project segment `projects/{p}/…`                           | **parsed, validated, then ignored** — single-tenant; resource ids are global across projects |
| Ingestion sources (topic / subscription)                   | **rejected** (`INVALID_ARGUMENT`) — no KubeMQ analog                                         |
| Export subscriptions (BigQuery / Cloud Storage / Bigtable) | **rejected** (`INVALID_ARGUMENT`)                                                            |
| REST / JSON v1 (grpc-gateway)                              | **not served** — gRPC only                                                                   |
| Google OAuth2 / JWT / IAM                                  | **not validated** — emulator mode, no auth                                                   |

## The documented gotchas [#the-documented-gotchas]

These behaviors deviate from real Google Cloud Pub/Sub and are easy to miss until a corner case
hits production. Each is documented in depth where shown:

| # | Gotcha                                                                                                                                                                                 | Where documented                                                                                                                                                                                                  |
| - | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | **Exactly-once is node-local** — an `ack_id` minted on one node is invalid on another; pin a subscription's StreamingPull to one node (sticky LB) or accept at-least-once across nodes | [Subscribing](/connectors/gcp-pub-sub/how-to/subscribing), [Reliability](/connectors/gcp-pub-sub/how-to/reliability), [Migrating from Google Cloud Pub/Sub](/connectors/gcp-pub-sub/reference/migration-from-gcp) |
| 2 | **Project id parsed but ignored** — resource ids are global across projects                                                                                                            | [Getting Started](/connectors/gcp-pub-sub/tutorials/getting-started), [Channel Mapping](/connectors/gcp-pub-sub/reference/channel-mapping)                                                                        |
| 3 | **Credentials cleared / insecure path when `PUBSUB_EMULATOR_HOST` is set** — the SDK skips Google auth and dials insecure gRPC                                                         | [Connectivity & Emulator Mode](/connectors/gcp-pub-sub/how-to/connectivity-and-emulator-mode)                                                                                                                     |
| 4 | **Filtering is an attributes-only CEL-subset** — malformed → `INVALID_ARGUMENT`                                                                                                        | [Message Filtering](/connectors/gcp-pub-sub/how-to/filtering), [Limits & Rules](/connectors/gcp-pub-sub/reference/limits-and-rules)                                                                               |
| 5 | **Retention clamped to the broker maximum** — `GetTopic` / `GetSubscription` echo the requested value; fan-out, seek, and the dashboard use the clamped value                          | [Limits & Rules](/connectors/gcp-pub-sub/reference/limits-and-rules), [Seek & Snapshots](/connectors/gcp-pub-sub/how-to/seek-and-snapshots)                                                                       |
| 6 | **`max_delivery_attempts` must be 5..100** (0 = unset)                                                                                                                                 | [Reliability](/connectors/gcp-pub-sub/how-to/reliability), [Limits & Rules](/connectors/gcp-pub-sub/reference/limits-and-rules)                                                                                   |
| 7 | **Topic ids may not start with `sub.`** (reserved namespace)                                                                                                                           | [Channel Mapping](/connectors/gcp-pub-sub/reference/channel-mapping), [Limits & Rules](/connectors/gcp-pub-sub/reference/limits-and-rules)                                                                        |
| 8 | **Seek of a pre-window timestamp clamps to the earliest retained message** (not an error)                                                                                              | [Seek & Snapshots](/connectors/gcp-pub-sub/how-to/seek-and-snapshots)                                                                                                                                             |
| 9 | **gRPC only — no REST/JSON v1** (grpc-gateway not used)                                                                                                                                | [Architecture](/connectors/gcp-pub-sub/concepts/architecture), this page                                                                                                                                          |

<Callout type="info">
  Two further documented deviations are surfaced in the reference docs but are not headline gotchas:
  the **unary invalid-ack** returns `FAILED_PRECONDITION` + `ErrorInfo(PERMANENT_FAILURE_INVALID_ACK_ID)`
  (matching the real SDK contract, not a literal `INVALID_ARGUMENT`), and **export subscriptions /
  ingestion are rejected** while `kms_key_name` is accepted-and-ignored. Both live in
  [Error Codes](/connectors/gcp-pub-sub/reference/error-codes) and
  [Migrating from Google Cloud Pub/Sub](/connectors/gcp-pub-sub/reference/migration-from-gcp).
</Callout>

## Related [#related]

<Cards>
  <Card title="Channel Mapping" href="/connectors/gcp-pub-sub/reference/channel-mapping" description="The gcp.{topic} / gcp.sub.{subscription} grammar, the per-key channels, and the reserved tags." />

  <Card title="Limits & Rules" href="/connectors/gcp-pub-sub/reference/limits-and-rules" description="The Google-exact limits and the CONNECTORS_GCP_* config caps behind each rejection above." />

  <Card title="Error Codes" href="/connectors/gcp-pub-sub/reference/error-codes" description="The gRPC status codes the connector returns for each rejected operation." />

  <Card title="Migrating from Google Cloud Pub/Sub" href="/connectors/gcp-pub-sub/reference/migration-from-gcp" description="The deviations from real Pub/Sub and the endpoint-only switch." />
</Cards>
