<a id="cc-opensearch-sink"></a>

# OpenSearch Sink Connector for Confluent Cloud

The fully managed OpenSearch Sink connector for Confluent Cloud moves data from an
Apache Kafka® topic to a specified [OpenSearch index](https://opensearch.org/docs/latest/im-plugin/#introduction-to-indexing)
facilitating real time analysis of data in OpenSearch. The connector supports
Avro, JSON Schema, JSON (schemaless), and Protobuf data output format from
Apache Kafka® topics.

#### NOTE
If you require private networking for fully managed connectors, make sure to set up the proper
networking beforehand. For more information, see [Manage Networking for Confluent Cloud Connectors](networking/internet-resource.md#clusters-connect-cloud).

## Features

The OpenSearch Sink connector includes the following features:

* **Automatic index creation**: The connector supports automatic creation of
  indexes depending on the OpenSearch configuration.
* **Multi-indexing**: The connector allows you to create and manage up to 5
  indexes simultaneously.
* **Input data formats**: The connector supports Avro, JSON Schema, Protobuf, or
  JSON (schemaless) input data formats. [Schema Registry](../get-started/schema-registry.md#cloud-sr-config)
  must be enabled to use a Schema Registry-based format (for example, Avro, JSON Schema, or
  Protobuf).
* **Input key formats**: The connector supports Avro, JSON Schema, Protobuf,
  JSON (schemaless), String, or Bytes input key formats. The default is Bytes.
  [Schema Registry](../get-started/schema-registry.md#cloud-sr-config) must be enabled to use a Schema Registry-based
  format (for example, Avro, JSON Schema, or Protobuf). Setting the key format
  ensures the Kafka record key deserializes correctly when used as the
  OpenSearch document `_id` or in delete operations.
* **Dual-platform OpenSearch support**: The connector supports both AWS
  OpenSearch and OSS OpenSearch.
* **Topic-to-index mapping**: The connector supports mapping a topic to a
  specific OpenSearch Index.
* **Flexible write operations**: The connector supports both `INSERT` and `UPSERT` write
  methods. With `UPSERT`, the Kafka record key determines the operation: the connector upserts records with a non-null key and inserts records with a null key as new documents. The default method is `INSERT`.
* **Document ID from the record key (INSERT)**: When using the `INSERT` write method,
  set `indexN.insert.key.as.id` to `true` to use the Kafka record key as the
  OpenSearch document `_id` instead of an auto-generated ID. If a document with
  the same `_id` already exists, the connector replaces it. The `UPSERT`
  write method ignores this setting and always uses the Kafka record key as the
  `_id`.
* **Schema management**: The connector supports Schema Registry, Schema Context
  and Reference Subject Naming Strategy.
* **Topic Mutating SMTs Support**: The connector also supports the following SMTs:
  - `org.apache.kafka.connect.transforms.TimestampRouter`
  - `io.confluent.connect.transforms.MessageTimestampRouter`
  - `io.confluent.connect.transforms.ExtractTopic`
  - `io.confluent.connect.cloud.transforms.TopicRegexRouter`

  For details, see the [Single Message Transformations](single-message-transforms.md#cc-single-message-transforms) documentation.

For more information and examples to use with the Confluent Cloud API for Connect,
see the [Confluent Cloud API for Connect Usage Examples](connect-api-section.md#ccloud-connect-api) section.

## Limitations

Be sure to review the following information.

* For connector limitations, see [Opensearch Sink Connector](limits.md#cc-opensearch-sink-limits) limitations.
* If you plan to use one or more Single Message Transformations (SMTs), see
  [SMT Limitations](single-message-transforms.md#cc-single-message-transforms-limitations).

## Quick Start

Use this quick start to get up and running with the Confluent Cloud OpenSearch
Sink connector. The quick start provides the basics of selecting the
connector and configuring it to stream events to an OpenSearch deployment.

<a id="cc-opensearch-sink-prereqs"></a>

Prerequisites

- Authorized access to a [Confluent Cloud](https://www.confluent.io/confluent-cloud/) cluster on Amazon Web Services
  (AWS), Microsoft Azure (Azure), or Google Cloud.
- The Confluent CLI installed and configured for the cluster. For help, see
  [Install the Confluent CLI](https://docs.confluent.io/confluent-cli/current/install.html).
- [Schema Registry](../get-started/schema-registry.md#cloud-sr-config) must be enabled to use a
  Schema Registry-based format (for example, Avro, JSON Schema, or Protobuf).
- For networking considerations, see
  [Networking and DNS](overview.md#connect-internet-access-resources). To use a set of public egress IP
  addresses, see [Public Egress IP Addresses for Confluent Cloud Connectors](static-egress-ip.md#cc-static-egress-ips).

- Kafka cluster credentials. The following lists the different ways you can provide credentials.
  - Enter an existing [service account](service-account.md#s3-cloud-service-account) resource ID.
  - Create a Confluent Cloud [service account](service-account.md#s3-cloud-service-account) for the connector. Make sure to review the ACL entries required in the [service account documentation](service-account.md#s3-cloud-service-account). Some connectors have specific ACL requirements.
  - Create a Confluent Cloud API key and secret. To create a key and secret, you can use [confluent api-key create](https://docs.confluent.io/confluent-cli/current/command-reference/api-key/confluent_api-key_create.html) *or* you can autogenerate the API key and secret directly in the Cloud Console when setting up the connector.

- You must have the required cluster and index permissions.
  See [OpenSearch permissions](#cc-opensearch-sink-permissions) for a complete list of required
  permissions.

<a id="cc-opensearch-sink-permissions"></a>

### OpenSearch permissions

The OpenSearch Sink connector requires specific permissions to write data to your
OpenSearch cluster. The user account used for authentication must have the
appropriate cluster and index-level permissions.

### Required permissions

The connector requires the following index-level permissions on the target indexes:

**For INSERT operations**

You need the following minimum permissions:

- `create` - Create new documents
- `index` - Index documents
- `write` - Write data to indexes
- `create_index` - Create indexes (if automatic index creation is enabled)
- `indices:admin/mapping/put` - Update index mappings

**For UPSERT operations**

You need the following additional permissions:

- `update` - Update existing documents
- `delete` - Delete documents (used during update operations)

The connector requires the following cluster-level permissions: `monitor` and `manage`.
Grant broader permissions (such as `all`) only if explicitly required by your organization’s security policies or specific operational needs.

### Using the Confluent Cloud Console

#### Step 1: Launch your Confluent Cloud cluster

To create and launch a Kafka cluster in Confluent Cloud, see [Create a kafka cluster in Confluent Cloud](../get-started/index.md#cloud-create-kafka-cluster).

#### Step 2: Add a connector

In the left navigation menu, click **Connectors**. If you already have connectors in your cluster, click **+ Add
connector**.

#### Step 3: Select your connector

Click the **OpenSearch Sink** connector card.

![OpenSearch Sink Connector Card](images/ccloud-opensearch-sink-icon.png)

#### Step 4: Enter the connector details

Note the following:

* Ensure you have completed all the [prerequisites](#cc-opensearch-sink-prereqs).
* An asterisk ( \* ) designates a required entry.

At the **Add OpenSearch Sink connector** screen, complete the following:

### Select or create a topic

If you’ve already populated your Kafka topics, select the topics you want
to connect from the **Topics** list.

To create a new topic, click **Add a new topic**. To use the default
topic settings, click **Create with defaults**. To modify the topic
settings, click **Show advanced settings**, update accordingly, and then
click **Save & Create**.

### Kafka access

1. Select the way you want to provide **Kafka Cluster credentials**. You can
   choose one of the following options:
   - **My account**: This setting allows your connector to globally access everything
     that you have access to. With a user account, the connector uses an API key and
     secret to access the Kafka cluster. This option is not recommended for production.
   - **Service account**: This setting limits the access for your connector by using a
     [service account](service-account.md#s3-cloud-service-account). This option is recommended for
     production.
   - **Use an existing API key**: This setting allows you to specify an API key and a
     secret pair. You can use an existing pair or create a new one. This method is not
     recommended for production environments.

   #### NOTE
   Freight clusters support only service accounts for Kafka authentication.
2. Click **Continue**.

### Authentication

1. Configure the authentication properties:

   **Authentication**
   - **OpenSearch Instance URL**: The OpenSearch instance URL. For example, `https://your-opensearch-instance.com/`.
   - **Endpoint Authentication Type**: The authentication type of the endpoint.
   - **Auth Username**: The username to be used with an endpoint requiring basic authentication.
   - **Auth Password**: The password to be used with an endpoint requiring basic authentication.
   - **SSL Enabled**: Set whether to connect to the endpoint using SSL. If set to `true`,
     enter the following details mentioned below.
   - **Key Store**: The keystore that contains the client certificate and private key. Supported formats are JKS or PKCS12. File system paths are not supported.
   - **Keystore Password**: The store password for the key store file.
   - **Key Password**: The password for the private key in the key store file.
   - **Trust Store**: The trust store that contains the server CA certificate(s). Supported formats are JKS or PKCS12. File system paths are not supported.
   - **Trust Store Password**: The trust store password containing a server CA certificate.
   - **SSL Protocol**: The protocol to use for SSL connections.
2. Click **Continue**.

### Configuration

#### NOTE
Configuration properties that are not shown in the
Cloud Console use the default values. See
[Configuration Properties](#cc-opensearch-sink-config-properties) for all property values
and definitions.

- **Input Kafka record value format**: Select the **Input Kafka record value format** (data coming from the Kafka
  topic): AVRO, BYTES, JSON_SR, JSON (schemaless) PROTOBUF. A valid
  schema must be available in [Schema Registry](../get-started/schema-registry.md#cloud-sr-config) to
  use a schema-based message format (for example, AVRO, JSON_SR, or
  PROTOBUF).
- **Input Kafka record key format**: Sets the input Kafka record key format.
  Valid entries are `AVRO`, `BYTES`, `JSON`,
  `JSON_SR`, `PROTOBUF`, or `STRING`.

  #### NOTE
  You need Confluent Cloud Schema Registry configured to use a
  schema-based message format like `AVRO`, `JSON_SR`, and `PROTOBUF`.

**Indexes**

- **Number of indexes**: Enter the number of indexes to push data to in the **Indexes** field. Note that this
  value should be less than or equal to 5. If you entered 2 in the **Indexes** field,
  you should see 2 index configuration sections with the following fields to set.

**Index 1 configuration**

- **Index**: The index name. This name together with the OpenSearch
  Instance URL forms the complete HTTP(S) URL.
- **Topic**: The topic from which data will be pulled for this index.
- **Behavior for null valued records**: Determines how the connector handles records with a non-null key and a null
  value (also known as Kafka tombstone records) for each index.
  Valid options are `IGNORE`, `DELETE` and `FAIL`.
- **Batch Size**: The size of the batch of records to be sent to the OpenSearch. Note that Basic and Standard Clusters
  may experience throughput limitations, even with a higher batch size.
- **Report only status code to success topic**: Specifies whether to report only the status code to the success topic. If the API response
  payload is huge, it is recommended to set this to `true` for better throughput.
- **Write Method**: Defines how the connector writes documents to an index. `INSERT` adds only new
  documents. `UPSERT` uses the Kafka record key to determine the operation.
  It upserts (updates if the key exists, inserts if it does not) records with a
  non-null key and inserts records with a null key as new documents. The default method is `INSERT`.

  #### NOTE
  When the Write Method is set to `UPSERT`, the Kafka record key must be a
  string or bytes because OpenSearch only accepts string document IDs.
- **Use Kafka Key As Document ID**: Applies only to the INSERT write method. When set to `true`, the OpenSearch document `_id` is set from the Kafka record key instead of being auto-generated by OpenSearch. If a document with the same `_id` already exists, it is replaced. This setting is ignored for the UPSERT write method, which always uses the Kafka key as the `_id`.

**Index 2 configuration**

- **Index**: The index name. This name together with the OpenSearch
  Instance URL forms the complete HTTP(S) URL.
- **Topic**: The topic from which data will be pulled for this index.
- **Behavior for null valued records**: Determines how the connector handles records with a non-null key and a null
  value (also known as Kafka tombstone records) for each index.
  Valid options are `IGNORE`, `DELETE` and `FAIL`.
- **Batch Size**: The size of the batch of records to be sent to the OpenSearch. Note that Basic and Standard Clusters
  may experience throughput limitations, even with a higher batch size.
- **Report only status code to success topic**: Specifies whether to report only the status code to the success topic. If the API response
  payload is huge, it is recommended to set this to `true` for better throughput.
- **Write Method**: Defines how the connector writes documents to an index. `INSERT` adds only new
  documents. `UPSERT` uses the Kafka record key to determine the operation.
  It upserts (updates if the key exists, inserts if it does not) records with a
  non-null key and inserts records with a null key as new documents. The default method is `INSERT`.

  #### NOTE
  When the Write Method is set to `UPSERT`, the Kafka record key must be a
  string or bytes because OpenSearch only accepts string document IDs.
- **Use Kafka Key As Document ID**: Applies only to the INSERT write method. When set to `true`, the OpenSearch document `_id` is set from the Kafka record key instead of being auto-generated by OpenSearch. If a document with the same `_id` already exists, it is replaced. This setting is ignored for the UPSERT write method, which always uses the Kafka key as the `_id`.

**Index 3 configuration**

- **Index**: The index name. This name together with the OpenSearch
  Instance URL forms the complete HTTP(S) URL.
- **Topic**: The topic from which data will be pulled for this index.
- **Behavior for null valued records**: Determines how the connector handles records with a non-null key and a null
  value (also known as Kafka tombstone records) for each index.
  Valid options are `IGNORE`, `DELETE` and `FAIL`.
- **Batch Size**: The size of the batch of records to be sent to the OpenSearch. Note that Basic and Standard Clusters
  may experience throughput limitations, even with a higher batch size.
- **Report only status code to success topic**: Specifies whether to report only the status code to the success topic. If the API response
  payload is huge, it is recommended to set this to `true` for better throughput.
- **Write Method**: Defines how the connector writes documents to an index. `INSERT` adds only new
  documents. `UPSERT` uses the Kafka record key to determine the operation.
  It upserts (updates if the key exists, inserts if it does not) records with a
  non-null key and inserts records with a null key as new documents. The default method is `INSERT`.

  #### NOTE
  When the Write Method is set to `UPSERT`, the Kafka record key must be a
  string or bytes because OpenSearch only accepts string document IDs.
- **Use Kafka Key As Document ID**: Applies only to the INSERT write method. When set to `true`, the OpenSearch document `_id` is set from the Kafka record key instead of being auto-generated by OpenSearch. If a document with the same `_id` already exists, it is replaced. This setting is ignored for the UPSERT write method, which always uses the Kafka key as the `_id`.

**Index 4 configuration**

- **Index**: The index name. This name together with the OpenSearch
  Instance URL forms the complete HTTP(S) URL.
- **Topic**: The topic from which data will be pulled for this index.
- **Behavior for null valued records**: Determines how the connector handles records with a non-null key and a null
  value (also known as Kafka tombstone records) for each index.
  Valid options are `IGNORE`, `DELETE` and `FAIL`.
- **Batch Size**: The size of the batch of records to be sent to the OpenSearch. Note that Basic and Standard Clusters
  may experience throughput limitations, even with a higher batch size.
- **Report only status code to success topic**: Specifies whether to report only the status code to the success topic. If the API response
  payload is huge, it is recommended to set this to `true` for better throughput.
- **Write Method**: Defines how the connector writes documents to an index. `INSERT` adds only new
  documents. `UPSERT` uses the Kafka record key to determine the operation.
  It upserts (updates if the key exists, inserts if it does not) records with a
  non-null key and inserts records with a null key as new documents. The default method is `INSERT`.

  #### NOTE
  When the Write Method is set to `UPSERT`, the Kafka record key must be a
  string or bytes because OpenSearch only accepts string document IDs.
- **Use Kafka Key As Document ID**: Applies only to the INSERT write method. When set to `true`, the OpenSearch document `_id` is set from the Kafka record key instead of being auto-generated by OpenSearch. If a document with the same `_id` already exists, it is replaced. This setting is ignored for the UPSERT write method, which always uses the Kafka key as the `_id`.

**Index 5 configuration**

- **Index**: The index name. This name together with the OpenSearch
  Instance URL forms the complete HTTP(S) URL.
- **Topic**: The topic from which data will be pulled for this index.
- **Behavior for null valued records**: Determines how the connector handles records with a non-null key and a null
  value (also known as Kafka tombstone records) for each index.
  Valid options are `IGNORE`, `DELETE` and `FAIL`.
- **Batch Size**: The size of the batch of records to be sent to the OpenSearch. Note that Basic and Standard Clusters
  may experience throughput limitations, even with a higher batch size.
- **Report only status code to success topic**: Specifies whether to report only the status code to the success topic. If the API response
  payload is huge, it is recommended to set this to `true` for better throughput.
- **Write Method**: Defines how the connector writes documents to an index. `INSERT` adds only new
  documents. `UPSERT` uses the Kafka record key to determine the operation.
  It upserts (updates if the key exists, inserts if it does not) records with a
  non-null key and inserts records with a null key as new documents. The default method is `INSERT`.

  #### NOTE
  When the Write Method is set to `UPSERT`, the Kafka record key must be a
  string or bytes because OpenSearch only accepts string document IDs.
- **Use Kafka Key As Document ID**: Applies only to the INSERT write method. When set to `true`, the OpenSearch document `_id` is set from the Kafka record key instead of being auto-generated by OpenSearch. If a document with the same `_id` already exists, it is replaced. This setting is ignored for the UPSERT write method, which always uses the Kafka key as the `_id`.

### **Show advanced configurations**

- **Schema context**: Select a schema context to use for this connector, if using
  a schema-based data format. This property defaults to the **Default** context,
  which configures the connector to use the default schema set up for Schema Registry in your
  Confluent Cloud environment. A schema context allows you to use separate schemas (like
  schema sub-registries) tied to topics in different Kafka clusters that share the
  same Schema Registry environment. For example, if you select a non-default context, a
  **Source** connector uses only that schema context to register a schema and a
  **Sink** connector uses only that schema context to read from. For more
  information about setting up a schema context, see [What are schema contexts and when should you use them?](../sr/faqs-cc.md#faq-schema-contexts).

**Additional Configs**

- **Value Converter Replace Null With Default**: Specifies whether to replace fields that have a default value and that are null to the default value. When set to `true`, the connector uses the default value; otherwise, it uses `null`. Applies to the `JSON` converter.
- **Value Converter Schema ID Deserializer**: Sets the class name of the schema ID deserializer for values. The deserializer reads schema IDs from message headers.
- **Value Converter Reference Subject Name Strategy**: Sets the subject reference name strategy for values. Valid entries are `DefaultReferenceSubjectNameStrategy` or `QualifiedReferenceSubjectNameStrategy`. You can use this strategy only with `PROTOBUF` format; the default strategy is `DefaultReferenceSubjectNameStrategy`.
- **Schema ID For Value Converter**: Sets the schema ID to use for deserialization when using `ConfigSchemaIdDeserializer`. This lets you specify a fixed schema ID for deserializing message values. This property is applicable only when `value.converter.value.schema.id.deserializer` is set to `ConfigSchemaIdDeserializer`.
- **Value Converter Schemas Enable**: Includes schema within each of the serialized values. Input messages must contain `schema` and `payload` fields and must not contain additional fields. For plain `JSON` data, set this to `false`. Applies to the `JSON` converter.
- **Errors Tolerance**: Use this property to configure the connector’s error handling behavior.

  #### WARNING
  Use this property with caution for sink connectors, as it can lead to data loss. If you set this property to `all`, the connector does not fail on errant records, but logs them (and sends to DLQ for sink connectors) and continues processing. If you set this property to `none`, the connector task fails on errant records.
- **Value Converter Ignore Default For Nullables**: When set to `true`, this property ensures that the corresponding record in Kafka is `null`, instead of showing the default column value. Applies to the `AVRO`, `PROTOBUF`, and `JSON_SR` converters.
- **Key Converter Schema ID Deserializer**: Sets the class name of the schema ID deserializer for keys. The deserializer reads schema IDs from message headers.
- **Value Converter Decimal Format**: Specifies the `JSON` or `JSON_SR` serialization format for Connect `DECIMAL` logical type values with two allowed literals:
  `BASE64` to serialize `DECIMAL` logical types as base64 encoded binary data, and
  `NUMERIC` to serialize `DECIMAL` logical type values in `JSON` or `JSON_SR` as a number representing the decimal value.
- **Schema GUID For Key Converter**: Sets the schema GUID to use for deserialization when using `ConfigSchemaIdDeserializer`. This lets you specify a fixed schema GUID for deserializing message keys. This property is applicable only when `key.converter.key.schema.id.deserializer` is set to `ConfigSchemaIdDeserializer`.
- **Schema GUID For Value Converter**: Sets the schema GUID to use for deserialization when using `ConfigSchemaIdDeserializer`. This lets you specify a fixed schema GUID for deserializing message values. This property is applicable only when `value.converter.value.schema.id.deserializer` is set to `ConfigSchemaIdDeserializer`.
- **Value Converter Connect Meta Data**: Enables the Connect converter to add its metadata to the output schema. Applies to Avro converters.
- **Value Converter Value Subject Name Strategy**: Determines how to construct the subject name under which the value schema is registered with Schema Registry.
- **Key Converter Key Subject Name Strategy**: Determines how to construct the subject name for key schema registration.
- **Schema ID For Key Converter**: Sets the schema ID to use for deserialization when using `ConfigSchemaIdDeserializer`. This lets you specify a fixed schema ID for deserializing message keys. This property is applicable only when `key.converter.key.schema.id.deserializer` is set to `ConfigSchemaIdDeserializer`.

**Auto-restart policy**

- **Enable Connector Auto-restart**: Enables the auto-restart behavior of the connector and its
  task in the event of user-actionable errors. Defaults to `true`, enabling the connector to
  automatically restart in case of user-actionable errors. Set this property to `false` to
  disable auto-restart for failed connectors. If disabled, you must manually restart the connector.

**Consumer configuration**

- **Max poll interval(ms)**: Sets the maximum delay between subsequent consume requests to Kafka. Use this property to
  improve connector performance in cases when the connector cannot send records to the sink system.
  The default is 300,000 milliseconds (5 minutes).
- **Max poll records**: Sets the maximum number of records to consume from Kafka in a single request. Use this property to
  improve connector performance in cases when the connector cannot send records to the sink system.
  The default is 500 records.

**Behavior on error**

- **Behavior On Errors**: Behavior setting for handling error responses from HTTP requests. Must be configured
  to one of the following: `IGNORE` or `FAIL`.

**Retry configurations**

- **Retry Backoff Policy**: The backoff policy to use in terms of a
  retry. Must be configured to `CONSTANT_VALUE` OR
  `EXPONENTIAL_WITH_JITTER`.
- **Retry Backoff (ms)**: The time in milliseconds to wait following
  an error before the connector retries the task.
- **Retry HTTP Status Codes**: The HTTP response status codes
  returned that prompt the connector to retry the request. Enter a
  comma- separated list of codes or range of codes. Ranges are
  specified with a start and optional end code. Range boundaries are
  inclusive. For example: `400-` includes all codes greater than
  or equal to `400` and `400-500` includes codes from 400 to
  500, including 500. Multiple ranges and single codes can be
  specified together to achieve fine-grained control over retry
  behavior. For example: `404,408,500-` prompts the connector to
  retry on `404 NOT FOUND`, `408 REQUEST TIMEOUT`, and all
  `5xx` error codes. Note that some status codes are always
  retried, such as unauthorized, timeouts, and too many requests.
- **Maximum Retries**: The maximum number of times the connector
  retries a request when an error occurs, before the task fails.

**Transforms**

- **Single Message Transformations**: To add a new SMT, see [Add transforms](single-message-transforms.md#cc-single-message-transforms-ui).
  For more information about unsupported SMTs, see
  [Unsupported transformations](single-message-transforms.md#cc-single-message-transforms-unsupported-transforms).

**Processing position**

- **Set offsets**: Click **Set offsets** to define a specific offset for
  this connector to begin procession data from. For more information
  on managing offsets, see [Manage offsets](offsets.md#connect-custom-offsets).

- Click **Continue**.

### Sizing

Based on the number of topic partitions you select, you will be provided
with a recommended number of tasks.

1. To change the number of recommended tasks, enter the number of
   [tasks](/platform/current/connect/concepts.html#tasks) for the connector to use in
   the **Tasks** field.
2. Click **Continue**.

### Review and Launch

1. Verify the connection details.
2. Click **Launch**.

   The status for the connector should go from **Provisioning** to
   **Running**.

#### Step 5: Check the results in OpenSearch

Verify that new records are being added to your OpenSearch deployment.

For more information and examples to use with the Confluent Cloud API for Connect,
see the [Confluent Cloud API for Connect Usage Examples](connect-api-section.md#ccloud-connect-api) section.

### Using the Confluent CLI

Complete the following steps to set up and run the connector using the
Confluent CLI. Ensure you have completed all the [prerequisites](#cc-opensearch-sink-prereqs).

#### Step 1: List the available connectors

Enter the following command to list available connectors:

```none
confluent connect plugin list
```

#### Step 2: List the connector configuration properties

Enter the following command to show the connector configuration properties:

```none
confluent connect plugin describe <connector-plugin-name>
```

The command output shows the required and optional configuration properties.

#### Step 3: Create the connector configuration file

Create a JSON file that contains the connector configuration properties. The
following example shows required and optional connector properties.

```none
{
  "connector.class": "OpenSearchSink",
  "input.data.format": "JSON",
  "input.key.format": "BYTES",
  "kafka.auth.mode": "KAFKA_API_KEY",
  "kafka.api.key": "<my-kafka-api-key",
  "kafka.api.secret": "<my-kafka-api-secret",
  "name": "os_sink_connectors3ss2a",
  "instance.url": "https://your-opensearch-endpoint.example",
  "topics": "inventory,orders,users",
  "request.method": "POST",
  "tasks.max": "1",
  "indexes.num": "3",
  "auth.type": "BASIC",
  "connection.user": "username",
  "connection.password": "password",
  "index1.name" : "users_index",
  "index1.topic": "users",
  "index1.write.method": "INSERT",
  "index2.name" : "inventory_index",
  "index2.topic": "inventory",
  "index2.write.method": "UPSERT",
  "index3.name" : "orders",
  "index3.topic": "orders_index",
  "index3.write.method": "INSERT"
}
```

Note the following property definitions:

* `"connector.class"`: Identifies the connector plugin name.
* `"input.data.format"`:  Sets the input Kafka record value format (data coming
  from the Kafka topic). Valid entries are **AVRO**, **JSON_SR**, **PROTOBUF**,
  or **JSON**. You must have Confluent Cloud Schema Registry configured if using a schema-based
  message format (for example, Avro, JSON Schema, JSON, or Protobuf).
* `"input.key.format"`: Sets the format of the Kafka record key. Valid
  entries are **AVRO**, **BYTES**, **JSON**, **JSON_SR**, **PROTOBUF**, or
  **STRING**. You must have Confluent Cloud Schema Registry configured if using a schema-based
  message format (for example, Avro, JSON Schema, or Protobuf). The default
  is **BYTES**. Setting the key format ensures the record key deserializes
  correctly when used as the OpenSearch document `_id` or in delete
  operations.

* `"kafka.auth.mode"`: Identifies the connector authentication mode you want to use. There are two options: `SERVICE_ACCOUNT` or `KAFKA_API_KEY` (the default). To use an API key and secret, specify the configuration properties `kafka.api.key` and `kafka.api.secret`, as shown in the example configuration (above).  To use a [service account](service-account.md#s3-cloud-service-account), specify the **Resource ID** in the property `kafka.service.account.id=<service-account-resource-ID>`. To list the available service account resource IDs, use the following command:
  ```bash
  confluent iam service-account list
  ```

  For example:
  ```bash
  confluent iam service-account list

     Id     | Resource ID |       Name        |    Description
  +---------+-------------+-------------------+-------------------
     123456 | sa-l1r23m   | sa-1              | Service account 1
     789101 | sa-l4d56p   | sa-2              | Service account 2
  ```

* `"name"`: Sets a name for your new connector.
* `"instance.url"`: The OpenSearch instance URL. The URL you enter
  should look like this: `http://your-opensearch-instance.com/`.
* `"topics"`: Identifies the topic name or a comma-separated list of topic names.
* `"request.method"`: Enter an HTTP API Request Method. Only `POST` requests
  are supported.
* `"tasks.max"`: Enter the maximum number of
  [tasks](/platform/current/connect/concepts.html#tasks) for the connector to use. More
  tasks might improve performance.
* `"indexes.num"`: The number of indexes to push data to.
* `"indexN.write.method"`: Sets how documents are written. Set to `INSERT` to add
  only new documents. Set to `UPSERT` to use the Kafka record key to determine the
  operation. It upserts (updates if the key exists, inserts if it does not) records with a non-null key and inserts records with a null key as new documents. When you use `UPSERT` method, the Kafka record key must be a string or bytes because OpenSearch accepts only string document IDs.
  The default is
  `INSERT`.

**SMTs**: For details about adding SMTs using the Confluent CLI, see
the [Single Message Transformations](single-message-transforms.md#cc-single-message-transforms)
documentation. For a list of SMTs that are not supported with this connector,
see [Unsupported transformations](single-message-transforms.md#cc-single-message-transforms-unsupported-transforms).

For all property values and definitions, see
[Configuration Properties](#cc-opensearch-sink-config-properties).

#### Step 4: Load the configuration file and create the connector

Enter the following Confluent CLI command to load the configuration and start
the connector:

```none
confluent connect cluster create --config-file <file-name>.json
```

For example:

```none
confluent connect cluster create --config-file opensearch-sink-config.json
```

Example output:

```none
Created connector os_sink_connectors3ss2a lcc-ix4dl
```

#### Step 5: Check the connector status

Enter the following Confluent CLI command to check the connector status:

```none
confluent connect cluster list
```

Example output:

```none
ID          |       Name                 | Status  | Type
+-----------+----------------------------+---------+------+
lcc-ix4dl   | os_sink_connectors3ss2a    | RUNNING | sink
```

#### Step 6: Check the results in OpenSearch

Verify new records are being added to the OpenSearch deployment.

For more information and examples to use with the Confluent Cloud API for Connect,
see the [Confluent Cloud API for Connect Usage Examples](connect-api-section.md#ccloud-connect-api) section.

<a id="cc-opensearch-sink-config-properties"></a>

## Configuration Properties

Use the following configuration properties with the OpenSearch Sink connector.

### Which topics do you want to get data from?

`topics`
: Identifies the topic name or a comma-separated list of topic names.
  <br/>
  * Type: list
  * Importance: high

`errors.deadletterqueue.topic.name`
: The name of the topic to be used as the dead letter queue (DLQ) for messages that result in an error when processed by this sink connector, or its transformations or converters. Defaults to ‘dlq-${connector}’ if not set. The DLQ topic will be created automatically if it does not exist. You can provide `${connector}` in the value to use it as a placeholder for the logical cluster ID.
  <br/>
  * Type: string
  * Default: dlq-${connector}
  * Importance: low

`reporter.result.topic.name`
: The name of the topic to produce records to after successfully processing a sink record. Defaults to ‘success-${connector}’ if not set. You can provide `${connector}` in the value to use it as a placeholder for the logical cluster ID.
  <br/>
  * Type: string
  * Default: success-${connector}
  * Importance: low

`reporter.error.topic.name`
: The name of the topic to produce records to after each unsuccessful record sink attempt. Defaults to ‘error-${connector}’ if not set. You can provide `${connector}` in the value to use it as a placeholder for the logical cluster ID.
  <br/>
  * Type: string
  * Default: error-${connector}
  * Importance: low

### Schema Config

`schema.context.name`
: Add a schema context name. A schema context represents an independent scope in Schema Registry. It is a separate sub-schema tied to topics in different Kafka clusters that share the same Schema Registry instance. If not used, the connector uses the default schema configured for Schema Registry in your Confluent Cloud environment.
  <br/>
  * Type: string
  * Default: default
  * Importance: medium

### Input messages

`input.data.format`
: Sets the input Kafka record value format. Valid entries are AVRO, JSON_SR, PROTOBUF, JSON or BYTES. Note that you need to have Confluent Cloud Schema Registry configured if using a schema-based message format like AVRO, JSON_SR, and PROTOBUF.
  <br/>
  * Type: string
  * Default: JSON
  * Importance: high

`input.key.format`
: Sets the input Kafka record key format. Valid entries are AVRO, BYTES, JSON, JSON_SR, PROTOBUF, or STRING. Note that you need to have Confluent Cloud Schema Registry configured if using a schema-based message format like AVRO, JSON_SR, and PROTOBUF
  <br/>
  * Type: string
  * Default: BYTES
  * Valid Values: AVRO, BYTES, JSON, JSON_SR, PROTOBUF, STRING
  * Importance: high

### How should we connect to your data?

`name`
: Sets a name for your connector.
  <br/>
  * Type: string
  * Valid Values: A string at most 64 characters long
  * Importance: high

### Kafka Cluster credentials

`kafka.auth.mode`
: Kafka Authentication mode. It can be one of KAFKA_API_KEY or SERVICE_ACCOUNT. It defaults to KAFKA_API_KEY mode, whenever possible.
  <br/>
  * Type: string
  * Valid Values: SERVICE_ACCOUNT, KAFKA_API_KEY
  * Importance: high

`kafka.api.key`
: Kafka API Key. Required when kafka.auth.mode==KAFKA_API_KEY.
  <br/>
  * Type: password
  * Importance: high

`kafka.service.account.id`
: The Service Account that will be used to generate the API keys to communicate with Kafka Cluster.
  <br/>
  * Type: string
  * Importance: high

`kafka.api.secret`
: Secret associated with Kafka API key. Required when kafka.auth.mode==KAFKA_API_KEY.
  <br/>
  * Type: password
  * Importance: high

### Consumer configuration

`max.poll.interval.ms`
: The maximum delay between subsequent consume requests to Kafka. This configuration property may be used to improve the performance of the connector, if the connector cannot send records to the sink system. Defaults to 300000 milliseconds (5 minutes).
  <br/>
  * Type: long
  * Default: 300000 (5 minutes)
  * Valid Values: [60000,…,1800000] for non-dedicated clusters and [60000,…] for dedicated clusters
  * Importance: low

`max.poll.records`
: The maximum number of records to consume from Kafka in a single request. This configuration property may be used to improve the performance of the connector, if the connector cannot send records to the sink system. Defaults to 500 records.
  <br/>
  * Type: long
  * Default: 500
  * Valid Values: [1,…,500] for non-dedicated clusters and [1,…] for dedicated clusters
  * Importance: low

### Number of tasks for this connector

`tasks.max`
: Maximum number of tasks for the connector.
  <br/>
  * Type: int
  * Valid Values: [1,…]
  * Importance: high

### Authentication

`instance.url`
: The OpenSearch instance URL. For example: https://your-opensearch-instance.com/.
  <br/>
  * Type: string
  * Importance: high

`auth.type`
: Authentication type of the endpoint. Valid values are `NONE`, `BASIC`.
  <br/>
  * Type: string
  * Default: BASIC
  * Importance: high

`connection.user`
: The username to be used with an endpoint requiring basic authentication.
  <br/>
  * Type: string
  * Importance: medium

`connection.password`
: The password to be used with an endpoint requiring basic authentication.
  <br/>
  * Type: password
  * Importance: medium

`opensearch.ssl.enabled`
: Whether or not to connect to the endpoint via SSL.
  <br/>
  * Type: boolean
  * Default: false
  * Importance: medium

`opensearch.ssl.keystorefile`
: The keystore that contains the client certificate and private key. Supported formats are JKS or PKCS12. File system paths are not supported.
  <br/>
  * Type: password
  * Default: [hidden]
  * Importance: low

`opensearch.ssl.keystore.password`
: The store password for the key store file.
  <br/>
  * Type: password
  * Importance: high

`opensearch.ssl.key.password`
: The password for the private key in the key store file.
  <br/>
  * Type: password
  * Importance: high

`opensearch.ssl.truststorefile`
: The truststore that contains the server CA certificate(s). Supported formats are JKS or PKCS12. File system paths are not supported.
  <br/>
  * Type: password
  * Default: [hidden]
  * Importance: high

`opensearch.ssl.truststore.password`
: The trust store password containing a server CA certificate.
  <br/>
  * Type: password
  * Importance: high

`opensearch.ssl.protocol`
: The protocol to use for SSL connections
  <br/>
  * Type: string
  * Default: TLSv1.3
  * Importance: medium

### Behavior on error

`behavior.on.error`
: Error handling behavior setting for handling error response from HTTP requests.
  <br/>
  * Type: string
  * Default: FAIL
  * Importance: low

### Indexes

`indexes.num`
: The number of indexes to push data to. This value should be less than or equal to 5
  <br/>
  * Type: int
  * Default: 1
  * Valid Values: [1,…,5]
  * Importance: high

### Retry configurations

`retry.backoff.policy`
: The backoff policy to use in terms of retry - CONSTANT_VALUE or EXPONENTIAL_WITH_JITTER
  <br/>
  * Type: string
  * Default: EXPONENTIAL_WITH_JITTER
  * Importance: medium

`retry.backoff.ms`
: The initial duration in milliseconds to wait following an error before a retry attempt is made. Subsequent backoff attempts can be a constant value or exponential with jitter (can be configured using api\*.retry.backoff.policy parameter). Jitter adds randomness to the exponential backoff algorithm to prevent synchronized retries.
  <br/>
  * Type: int
  * Default: 3000 (3 seconds)
  * Valid Values: [100,…]
  * Importance: medium

`retry.on.status.codes`
: Comma-separated list of HTTP status codes or range of codes to retry on. Ranges are specified with start and optional end code. Range boundaries are inclusive. For instance, 400- includes all codes greater than or equal to 400. 400-500 includes codes from 400 to 500, including 500. Multiple ranges and single codes can be specified together to achieve fine-grained control over retry behavior. For example, 404,408,500- will retry on 404 NOT FOUND, 408 REQUEST TIMEOUT, and all 5xx error codes. Note that some status codes will always be retried, such as unauthorized, timeouts and too many requests.
  <br/>
  * Type: string
  * Default: 400-
  * Importance: medium

`max.retries`
: The maximum number of times to retry on errors before failing the task.
  <br/>
  * Type: int
  * Default: 3
  * Importance: medium

### Index 1 configuration

`index1.name`
: The index name together with the OpenSearch Instance URL will form the complete HTTP(S) URL. This path can be templated with offset information.
  <br/>
  * Type: string
  * Importance: high

`index1.topic`
: Topic from where data will be pulled for this Index
  <br/>
  * Type: string
  * Default: “”
  * Importance: high

`index1.behavior.on.null.values`
: How to handle records with a non-null key and a null value (i.e. Kafka tombstone records). Valid options are `IGNORE`, `DELETE` and `FAIL`
  <br/>
  * Type: string
  * Default: IGNORE
  * Importance: low

`index1.batch.size`
: Size of the batch of records to be sent to the OpenSearch. Note that Basic and Standard Clusters may experience throughput limitations, even with a higher batch size.
  <br/>
  * Type: int
  * Default: 1
  * Importance: low

`index1.report.only.status.code.to.success.topic`
: Whether to report only the status code to the success topic. If the API response payload is huge, it is recommended to set this to true, for better throughput.
  <br/>
  * Type: boolean
  * Default: false
  * Importance: medium

`index1.write.method`
: The write method determines how you add data to an index. The INSERT method inserts only new documents, while the UPSERT method updates existing documents or inserts new ones if they don’t exist.
  <br/>
  * Type: string
  * Default: INSERT
  * Valid Values: INSERT, UPSERT
  * Importance: high

`index1.insert.key.as.id`
: Applies only to the INSERT write method. When set to `true`, the OpenSearch document `_id` is set from the Kafka record key instead of being auto-generated by OpenSearch. If a document with the same `_id` already exists, it is replaced. This setting is ignored for the UPSERT write method, which always uses the Kafka key as the `_id`.
  <br/>
  * Type: boolean
  * Default: false
  * Importance: medium

### Index 2 configuration

`index2.name`
: The index name together with the OpenSearch Instance URL will form the complete HTTP(S) URL. This path can be templated with offset information.
  <br/>
  * Type: string
  * Importance: high

`index2.topic`
: Topic from where data will be pulled for this Index
  <br/>
  * Type: string
  * Default: “”
  * Importance: high

`index2.behavior.on.null.values`
: How to handle records with a non-null key and a null value (i.e. Kafka tombstone records). Valid options are `IGNORE`, `DELETE` and `FAIL`
  <br/>
  * Type: string
  * Default: IGNORE
  * Importance: low

`index2.batch.size`
: Size of the batch of records to be sent to the OpenSearch. Note that Basic and Standard Clusters may experience throughput limitations, even with a higher batch size.
  <br/>
  * Type: int
  * Default: 1
  * Importance: low

`index2.report.only.status.code.to.success.topic`
: Whether to report only the status code to the success topic. If the API response payload is huge, it is recommended to set this to true, for better throughput.
  <br/>
  * Type: boolean
  * Default: false
  * Importance: medium

`index2.write.method`
: The write method determines how you add data to an index. The INSERT method inserts only new documents, while the UPSERT method updates existing documents or inserts new ones if they don’t exist.
  <br/>
  * Type: string
  * Default: INSERT
  * Valid Values: INSERT, UPSERT
  * Importance: high

`index2.insert.key.as.id`
: Applies only to the INSERT write method. When set to `true`, the OpenSearch document `_id` is set from the Kafka record key instead of being auto-generated by OpenSearch. If a document with the same `_id` already exists, it is replaced. This setting is ignored for the UPSERT write method, which always uses the Kafka key as the `_id`.
  <br/>
  * Type: boolean
  * Default: false
  * Importance: medium

### Index 3 configuration

`index3.name`
: The index name together with the OpenSearch Instance URL will form the complete HTTP(S) URL. This path can be templated with offset information.
  <br/>
  * Type: string
  * Importance: high

`index3.topic`
: Topic from where data will be pulled for this Index
  <br/>
  * Type: string
  * Default: “”
  * Importance: high

`index3.behavior.on.null.values`
: How to handle records with a non-null key and a null value (i.e. Kafka tombstone records). Valid options are `IGNORE`, `DELETE` and `FAIL`
  <br/>
  * Type: string
  * Default: IGNORE
  * Importance: low

`index3.batch.size`
: Size of the batch of records to be sent to the OpenSearch. Note that Basic and Standard Clusters may experience throughput limitations, even with a higher batch size.
  <br/>
  * Type: int
  * Default: 1
  * Importance: low

`index3.report.only.status.code.to.success.topic`
: Whether to report only the status code to the success topic. If the API response payload is huge, it is recommended to set this to true, for better throughput.
  <br/>
  * Type: boolean
  * Default: false
  * Importance: medium

`index3.write.method`
: The write method determines how you add data to an index. The INSERT method inserts only new documents, while the UPSERT method updates existing documents or inserts new ones if they don’t exist.
  <br/>
  * Type: string
  * Default: INSERT
  * Valid Values: INSERT, UPSERT
  * Importance: high

`index3.insert.key.as.id`
: Applies only to the INSERT write method. When set to `true`, the OpenSearch document `_id` is set from the Kafka record key instead of being auto-generated by OpenSearch. If a document with the same `_id` already exists, it is replaced. This setting is ignored for the UPSERT write method, which always uses the Kafka key as the `_id`.
  <br/>
  * Type: boolean
  * Default: false
  * Importance: medium

### Index 4 configuration

`index4.name`
: The index name together with the OpenSearch Instance URL will form the complete HTTP(S) URL. This path can be templated with offset information.
  <br/>
  * Type: string
  * Importance: high

`index4.topic`
: Topic from where data will be pulled for this Index
  <br/>
  * Type: string
  * Default: “”
  * Importance: high

`index4.behavior.on.null.values`
: How to handle records with a non-null key and a null value (i.e. Kafka tombstone records). Valid options are `IGNORE`, `DELETE` and `FAIL`
  <br/>
  * Type: string
  * Default: IGNORE
  * Importance: low

`index4.batch.size`
: Size of the batch of records to be sent to the OpenSearch. Note that Basic and Standard Clusters may experience throughput limitations, even with a higher batch size.
  <br/>
  * Type: int
  * Default: 1
  * Importance: low

`index4.report.only.status.code.to.success.topic`
: Whether to report only the status code to the success topic. If the API response payload is huge, it is recommended to set this to true, for better throughput.
  <br/>
  * Type: boolean
  * Default: false
  * Importance: medium

`index4.write.method`
: The write method determines how you add data to an index. The INSERT method inserts only new documents, while the UPSERT method updates existing documents or inserts new ones if they don’t exist.
  <br/>
  * Type: string
  * Default: INSERT
  * Valid Values: INSERT, UPSERT
  * Importance: high

`index4.insert.key.as.id`
: Applies only to the INSERT write method. When set to `true`, the OpenSearch document `_id` is set from the Kafka record key instead of being auto-generated by OpenSearch. If a document with the same `_id` already exists, it is replaced. This setting is ignored for the UPSERT write method, which always uses the Kafka key as the `_id`.
  <br/>
  * Type: boolean
  * Default: false
  * Importance: medium

### Index 5 configuration

`index5.name`
: The index name together with the OpenSearch Instance URL will form the complete HTTP(S) URL. This path can be templated with offset information.
  <br/>
  * Type: string
  * Importance: high

`index5.topic`
: Topic from where data will be pulled for this Index
  <br/>
  * Type: string
  * Default: “”
  * Importance: high

`index5.behavior.on.null.values`
: How to handle records with a non-null key and a null value (i.e. Kafka tombstone records). Valid options are `IGNORE`, `DELETE` and `FAIL`
  <br/>
  * Type: string
  * Default: IGNORE
  * Importance: low

`index5.batch.size`
: Size of the batch of records to be sent to the OpenSearch. Note that Basic and Standard Clusters may experience throughput limitations, even with a higher batch size.
  <br/>
  * Type: int
  * Default: 1
  * Importance: low

`index5.report.only.status.code.to.success.topic`
: Whether to report only the status code to the success topic. If the API response payload is huge, it is recommended to set this to true, for better throughput.
  <br/>
  * Type: boolean
  * Default: false
  * Importance: medium

`index5.write.method`
: The write method determines how you add data to an index. The INSERT method inserts only new documents, while the UPSERT method updates existing documents or inserts new ones if they don’t exist.
  <br/>
  * Type: string
  * Default: INSERT
  * Valid Values: INSERT, UPSERT
  * Importance: high

`index5.insert.key.as.id`
: Applies only to the INSERT write method. When set to `true`, the OpenSearch document `_id` is set from the Kafka record key instead of being auto-generated by OpenSearch. If a document with the same `_id` already exists, it is replaced. This setting is ignored for the UPSERT write method, which always uses the Kafka key as the `_id`.
  <br/>
  * Type: boolean
  * Default: false
  * Importance: medium

### Additional Configs

`consumer.override.auto.offset.reset`
: Defines the behavior of the consumer when there is no committed position (which occurs when the group is first initialized) or when an offset is out of range. You can choose either to reset the position to the “earliest” offset (the default) or the “latest” offset. You can also select “none” if you would rather set the initial offset yourself and you are willing to handle out of range errors manually. More details: [https://docs.confluent.io/platform/current/installation/configuration/consumer-configs.html#auto-offset-reset](https://docs.confluent.io/platform/current/installation/configuration/consumer-configs.html#auto-offset-reset)
  <br/>
  * Type: string
  * Importance: low

`consumer.override.isolation.level`
: Controls how to read messages written transactionally. If set to read_committed, consumer.poll() will only return transactional messages which have been committed. If set to read_uncommitted (the default), consumer.poll() will return all messages, even transactional messages which have been aborted. Non-transactional messages will be returned unconditionally in either mode.  More details: [https://docs.confluent.io/platform/current/installation/configuration/consumer-configs.html#isolation-level](https://docs.confluent.io/platform/current/installation/configuration/consumer-configs.html#isolation-level)
  <br/>
  * Type: string
  * Importance: low

`header.converter`
: The converter class for the headers. This is used to serialize and deserialize the headers of the messages.
  <br/>
  * Type: string
  * Importance: low

`key.converter.use.schema.guid`
: The schema GUID to use for deserialization when using ConfigSchemaIdDeserializer. This allows you to specify a fixed schema GUID to be used for deserializing message keys. Only applicable when key.converter.key.schema.id.deserializer is set to ConfigSchemaIdDeserializer.
  <br/>
  * Type: string
  * Importance: low

`key.converter.use.schema.id`
: The schema ID to use for deserialization when using ConfigSchemaIdDeserializer. This allows you to specify a fixed schema ID to be used for deserializing message keys. Only applicable when key.converter.key.schema.id.deserializer is set to ConfigSchemaIdDeserializer.
  <br/>
  * Type: int
  * Importance: low

`value.converter.allow.optional.map.keys`
: Allow optional string map key when converting from Connect Schema to Avro Schema. Applicable for Avro Converters.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.auto.register.schemas`
: Specify if the Serializer should attempt to register the Schema.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.connect.meta.data`
: Allow the Connect converter to add its metadata to the output schema. Applicable for Avro Converters.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.enhanced.avro.schema.support`
: Enable enhanced schema support to preserve package information and Enums. Applicable for Avro Converters.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.enhanced.protobuf.schema.support`
: Enable enhanced schema support to preserve package information. Applicable for Protobuf Converters.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.flatten.unions`
: Whether to flatten unions (oneofs). Applicable for Protobuf Converters.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.generate.index.for.unions`
: Whether to generate an index suffix for unions. Applicable for Protobuf Converters.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.generate.struct.for.nulls`
: Whether to generate a struct variable for null values. Applicable for Protobuf Converters.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.int.for.enums`
: Whether to represent enums as integers. Applicable for Protobuf Converters.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.latest.compatibility.strict`
: Verify latest subject version is backward compatible when use.latest.version is true.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.object.additional.properties`
: Whether to allow additional properties for object schemas. Applicable for JSON_SR Converters.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.optional.for.nullables`
: Whether nullable fields should be specified with an optional label. Applicable for Protobuf Converters.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.optional.for.proto2`
: Whether proto2 optionals are supported. Applicable for Protobuf Converters.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.scrub.invalid.names`
: Whether to scrub invalid names by replacing invalid characters with valid characters. Applicable for Avro and Protobuf Converters.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.use.latest.version`
: Use latest version of schema in subject for serialization when auto.register.schemas is false.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.use.optional.for.nonrequired`
: Whether to set non-required properties to be optional. Applicable for JSON_SR Converters.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.use.schema.guid`
: The schema GUID to use for deserialization when using ConfigSchemaIdDeserializer. This allows you to specify a fixed schema GUID to be used for deserializing message values. Only applicable when value.converter.value.schema.id.deserializer is set to ConfigSchemaIdDeserializer.
  <br/>
  * Type: string
  * Importance: low

`value.converter.use.schema.id`
: The schema ID to use for deserialization when using ConfigSchemaIdDeserializer. This allows you to specify a fixed schema ID to be used for deserializing message values. Only applicable when value.converter.value.schema.id.deserializer is set to ConfigSchemaIdDeserializer.
  <br/>
  * Type: int
  * Importance: low

`value.converter.wrapper.for.nullables`
: Whether nullable fields should use primitive wrapper messages. Applicable for Protobuf Converters.
  <br/>
  * Type: boolean
  * Importance: low

`value.converter.wrapper.for.raw.primitives`
: Whether a wrapper message should be interpreted as a raw primitive at root level. Applicable for Protobuf Converters.
  <br/>
  * Type: boolean
  * Importance: low

`errors.tolerance`
: Use this property if you would like to configure the connector’s error handling behavior. WARNING: This property should be used with CAUTION for SOURCE CONNECTORS as it may lead to dataloss. If you set this property to ‘all’, the connector will not fail on errant records, but will instead log them (and send to DLQ for Sink Connectors) and continue processing. If you set this property to ‘none’, the connector task will fail on errant records.
  <br/>
  * Type: string
  * Default: all
  * Importance: low

`key.converter.key.schema.id.deserializer`
: The class name of the schema ID deserializer for keys. This is used to deserialize schema IDs from the message headers.
  <br/>
  * Type: string
  * Default: io.confluent.kafka.serializers.schema.id.DualSchemaIdDeserializer
  * Importance: low

`key.converter.key.subject.name.strategy`
: How to construct the subject name for key schema registration.
  <br/>
  * Type: string
  * Default: TopicNameStrategy
  * Importance: low

`key.converter.replace.null.with.default`
: Whether to replace fields that have a default value and that are null to the default value. When set to true, the default value is used, otherwise null is used. Applicable for JSON Key Converter.
  <br/>
  * Type: boolean
  * Default: true
  * Importance: low

`key.converter.schemas.enable`
: Include schemas within each of the serialized keys. Input message keys must contain schema and payload fields and may not contain additional fields. For plain JSON data, set this to false. Applicable for JSON Key Converter.
  <br/>
  * Type: boolean
  * Default: false
  * Importance: low

`value.converter.decimal.format`
: Specify the JSON/JSON_SR serialization format for Connect DECIMAL logical type values with two allowed literals:
  <br/>
  BASE64 to serialize DECIMAL logical types as base64 encoded binary data and
  <br/>
  NUMERIC to serialize Connect DECIMAL logical type values in JSON/JSON_SR as a number representing the decimal value.
  <br/>
  * Type: string
  * Default: BASE64
  * Importance: low

`value.converter.flatten.singleton.unions`
: Whether to flatten singleton unions. Applicable for Avro and JSON_SR Converters.
  <br/>
  * Type: boolean
  * Default: false
  * Importance: low

`value.converter.ignore.default.for.nullables`
: When set to true, this property ensures that the corresponding record in Kafka is NULL, instead of showing the default column value. Applicable for AVRO,PROTOBUF and JSON_SR Converters.
  <br/>
  * Type: boolean
  * Default: false
  * Importance: low

`value.converter.reference.subject.name.strategy`
: Set the subject reference name strategy for value. Valid entries are DefaultReferenceSubjectNameStrategy or QualifiedReferenceSubjectNameStrategy. Note that the subject reference name strategy can be selected only for PROTOBUF format with the default strategy being DefaultReferenceSubjectNameStrategy.
  <br/>
  * Type: string
  * Default: DefaultReferenceSubjectNameStrategy
  * Importance: low

`value.converter.replace.null.with.default`
: Whether to replace fields that have a default value and that are null to the default value. When set to true, the default value is used, otherwise null is used. Applicable for JSON Converter.
  <br/>
  * Type: boolean
  * Default: true
  * Importance: low

`value.converter.schemas.enable`
: Include schemas within each of the serialized values. Input messages must contain schema and payload fields and may not contain additional fields. For plain JSON data, set this to false. Applicable for JSON Converter.
  <br/>
  * Type: boolean
  * Default: false
  * Importance: low

`value.converter.value.schema.id.deserializer`
: The class name of the schema ID deserializer for values. This is used to deserialize schema IDs from the message headers.
  <br/>
  * Type: string
  * Default: io.confluent.kafka.serializers.schema.id.DualSchemaIdDeserializer
  * Importance: low

`value.converter.value.subject.name.strategy`
: Determines how to construct the subject name under which the value schema is registered with Schema Registry.
  <br/>
  * Type: string
  * Default: TopicNameStrategy
  * Importance: low

### Auto-restart policy

`auto.restart.on.user.error`
: Enable connector to automatically restart on user-actionable errors.
  <br/>
  * Type: boolean
  * Default: true
  * Importance: medium

<a id="cc-opensearch-sink-faq"></a>

## Frequently asked questions

Find answers to frequently asked questions about the OpenSearch Sink connector for Confluent Cloud.

### Deployment model and product fit

#### Can I run the OpenSearch Sink connector on my own Kafka Connect cluster (self-managed)?

No. The OpenSearch Sink connector is available only as a fully managed connector on Confluent Cloud. It cannot be downloaded for
self-managed environments.

### Networking and connectivity

#### Why do I see `instance.url: Could not connect to the configured host:port`?

This error indicates the connector cannot reach the target OpenSearch URL from the Confluent Cloud workers. Common causes include:

* **Networking Mismatch:** If the cluster is `PRIVATE_LINK` or `PCC`, outbound traffic is not enabled by default.
* **Firewall Restrictions:** Confluent egress IP ranges or PrivateLink/VPC routes are not allowlisted in your upstream gateway or firewall.

**Checklist:**

1. **Check network type:** Is your cluster `PUBLIC`, `PRIVATE_LINK`, or `PCC`?
2. **Verify PrivateLink/PCC routing:** For `PRIVATE_LINK` or `PCC` clusters, ensure the VPC path from Confluent to your endpoint is correctly configured.
3. **Allowlist IPs:** Confirm the Confluent egress IPs (or VPC CIDRs) are allowlisted at your OpenSearch perimeter.
4. **Port check:** Ensure port `443` (or your custom port) is open.

#### Which IPs or CIDRs do I need to allowlist for the OpenSearch Sink connector?

Data egress originates from Confluent-managed infrastructure.

* Use the documented egress IP address ranges for your specific region and cloud provider. See [Public Egress IP Addresses for Confluent Cloud Connectors](static-egress-ip.md#cc-static-egress-ips) for details.
* For Azure Private Link, users often allowlist specific region CIDRs.

### Authentication and permissions

#### Why do I see `the connector failed to create an index due to invalid credentials`?

Although the error message mentions `invalid credentials`, this typically indicates insufficient permissions rather than incorrect authentication.

**Common causes:**

* **Insufficient index privileges:** The connector user/API key lacks required permissions for index creation, writes, or mapping updates.
* **Security configurations:** Security plugins (for example, X-Pack security, OpenSearch Security) can deny index creation even when general write privileges exist.
* **Managed service restrictions:** Some hosted OpenSearch offerings have policies that block index creation for specific credentials.

**Resolution:**

1. **Verify permissions:** Ensure the connector user has the required permissions listed in [OpenSearch permissions](#cc-opensearch-sink-permissions).
2. **Check security policies:** Review any index lifecycle management, tenant boundaries, or security policies that might block index creation.
3. **Test credentials:** Use the same credentials to manually create an index using the OpenSearch API to confirm permissions.

#### What are the minimum required permissions for the connector?

The connector requires different permissions based on the write method:

**For INSERT operations:**

* `create` - Create new documents.
* `index` - Index documents.
* `write` - Write data to indexes.
* `create_index` - Create indexes (if automatic index creation is enabled).
* `indices:admin/mapping/put` - Update index mappings.

**For UPSERT operations (in addition to INSERT permissions):**

* `update` - Update existing documents.
* `delete` - Delete documents (used during update operations).

**Cluster-level permissions:**

* `monitor` - Monitor cluster health.
* `manage` - Manage cluster resources.

For more details, see [OpenSearch permissions](#cc-opensearch-sink-permissions).

#### How do I configure authentication for AWS OpenSearch Service?

For AWS OpenSearch Service, you can use Basic authentication. Configure `auth.type=BASIC` with your OpenSearch username and password.

Ensure your security group and VPC configuration allow traffic from Confluent egress IPs.

### Data formatting and error handling

#### Why do I see `400 Bad Request` errors in my connector?

OpenSearch `400 Bad Request` errors typically indicate data format or schema issues:

**Common causes:**

* **Invalid document structure:** The Kafka record value doesn’t match the expected OpenSearch document format.
* **Type mismatches:** Field types in the data don’t match the OpenSearch index mapping.
* **Null key issues:** When using `UPSERT` write method with null record keys.
* **Invalid index names:** Index names contain invalid characters or patterns.

**Resolution:**

1. **Check connector logs:** Review the Dead Letter Queue (DLQ) topic `dlq-lcc-<connector-id>` for detailed error messages and sample records.
2. **Verify data format:** Ensure your `input.data.format` matches the actual data in your Kafka topic.
3. **Review index mappings:** Check that your OpenSearch index mappings are compatible with the incoming data.
4. **Configure null handling:** Set `Behavior for null valued records` appropriately (`IGNORE`, `DELETE`, or `FAIL`).

#### Why does my connector fail with `invalid_index_name_exception`?

This error occurs during connector validation or when OpenSearch rejects an index name.

**Common causes:**

* **Invalid characters:** Index names cannot contain uppercase letters, spaces, or characters like `:`, `\`, `/`, `*`, `?`, `"`, `<`, `>`, `|`.
* **Reserved prefixes:** Index names cannot start with `_`, `-`, or `+`.
* **AWS OpenSearch restrictions:** Some AWS OpenSearch versions have stricter validation rules.

**Resolution:**

1. **Review index names:** Ensure all configured index names (`index1.name`, `index2.name`, etc.) follow OpenSearch naming conventions.
2. **Use lowercase:** Keep index names lowercase and use only alphanumeric characters, hyphens, and underscores.
3. **Check version compatibility:** Verify your OpenSearch version supports your index naming pattern.

#### How do I handle schema evolution with the OpenSearch Sink connector?

The connector supports schema evolution when using schema-based formats (Avro, JSON Schema, Protobuf):

* **Backward compatible changes:** Adding optional fields works automatically. OpenSearch will accept documents with new fields.
* **Breaking changes:** Removing fields or changing field types can cause failures. Plan schema changes carefully.
* **Dynamic mapping:** OpenSearch can automatically create mappings for new fields, but this might not always produce the desired field types.

**Best practices:**

1. Use Schema Registry for schema management. For more information, see [Schema Registry](../get-started/schema-registry.md#cloud-sr-config).
2. Test schema changes in a non-production environment first.
3. Consider using explicit index mappings to control field types.

### Performance and timeouts

#### Why does my connector fail with `Regex replacement operation timed out after 100ms`?

This error indicates a timeout during JSON document wrapping for UPSERT operations.

**Common causes:**

* **Large documents:** Very large Kafka record values can exceed the processing timeout.
* **Infrastructure delays:** Scheduling delays in the connector runtime environment.

**Resolution:**

1. **Check document size:** Review the size of records in your Kafka topic. The connector error topic will contain sample records that failed.
2. **Contact support:** This timeout is not user-configurable. If you consistently see this error with normal-sized documents, contact [Confluent Support](https://support.confluent.io/).
3. **Consider INSERT mode:** If you don’t require upsert functionality, use `INSERT` write method instead.

#### Why is my connector slow or experiencing high latency?

Several factors can impact connector performance:

**Connector configuration:**

* **Batch size:** The `index1.batch.size` setting controls how many records are sent per batch. Default is 2000. Smaller batches reduce latency but increase API calls.
* **Number of tasks:** Increase `tasks.max` to parallelize processing across multiple topic partitions.

**OpenSearch side:**

* **Index refresh intervals:** More frequent refreshes impact write performance.
* **Replica count:** More replicas increase write latency.
* **Resource constraints:** Check OpenSearch cluster CPU, memory, and I/O utilization.

**Network:**

* **Latency between** Confluent Cloud **and OpenSearch:** Higher network latency increases end-to-end processing time.

### Connector provisioning and errors

#### Why is my connector stuck in `Provisioning` state?

If your connector remains in `Provisioning` state for more than a few minutes:

1. **Check validation errors:** Review the connector configuration in the Cloud Console for validation failures.
2. **Verify connectivity:** Ensure the `instance.url` is reachable from Confluent Cloud (see networking FAQ above).
3. **Check permissions:** Verify that your Kafka API key and OpenSearch credentials are valid.
4. **Review instance URL:** Ensure the OpenSearch instance URL is correctly formatted (for example, `https://your-opensearch-endpoint.example`).

If the issue persists after verification, contact [Confluent Support](https://support.confluent.io/).

#### Why does the connector fail with `TopicAuthorizationException`?

The connector automatically creates internal topics including the Dead Letter Queue (DLQ) topic. This error indicates insufficient permissions.

**Resolution:**

Ensure the connector’s service account has the following Kafka ACLs:

* `CREATE` on the cluster
* `DESCRIBE`, `WRITE`, and `READ` on the DLQ topic (`dlq-lcc-<connector-id>`)
* `READ` on the source topic(s)

The service account you select during connector configuration must have these permissions.

#### What should I do if my connector fails with `Exiting WorkerSinkTask due to unrecoverable exception`?

This generic error indicates an unexpected failure in the connector runtime.

**Troubleshooting steps:**

1. **Check error topic:** Review records in the error topic `error-lcc-<connector-id>` for specific error details.
2. **Review connector logs:** Error messages in logs often provide the root cause.
3. **Check behavior on errors:** Verify your `behavior.on.error` setting. If set to `FAIL`, the connector will stop on any error. Consider `IGNORE` for transient issues.
4. **Restart connector:** Some transient errors resolve after a restart.

If the error persists, gather connector logs and error topic samples and contact [Confluent Support](https://support.confluent.io/).

#### Can I reset or modify connector offsets?

Yes. You can manage connector offsets using the Confluent Cloud console or CLI:

* **View current offsets:** See which records have been processed.
* **Reset offsets:** Reprocess data from a specific offset position.
* **Skip records:** Advance the offset to skip problematic records.

For details, see [Manage connector offsets](offsets.md#connect-custom-offsets).

## Next Steps

* For an example that shows fully managed Confluent Cloud connectors in action with
  Confluent Cloud for Apache Flink, see the [Cloud ETL Demo](/platform/current/tutorials/examples/cloud-etl/docs/index.html).
  This example also shows how to use Confluent CLI to manage your resources in
  Confluent Cloud.
  [![image](images/topology.png)](https://docs.confluent.io/platform/current/tutorials/examples/cloud-etl/docs/index.html)
* Try [Confluent Cloud on AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-g5ujul6iovvcy?trk=14575e70-1766-4f20-8083-0c2757a1ec75&sc_channel=el)
  with $1000 of free usage for 30 days, and pay as you go. No credit card is
  required.
