Skip to main content

Google SecOps

GCP Security Target

Synopsis

The Google SecOps target forwards events to Google Security Operations using the Ingestion API. Supports both V1 and V2 API versions with unstructured logs or UDM (Unified Data Model) format submission.

Schema

- name: <string>
description: <string>
type: gcpsecops
pipelines: <pipeline[]>
status: <boolean>
properties:
api_version: <string>
send_events_as: <string>
udm_type: <string>
region: <string>
customer_id: <string>
authentication_method: <credentials|secret|apikey|apikeysecret>
service_account_credentials: <string>
service_account_credentials_secret: <string>
api_key: <string>
api_key_secret: <string>
default_log_type: <string>
log_text_field: <string>
namespace: <string>
custom_log_types:
- log_type: <string>
description: <string>
labels:
- key: <string>
value: <string>
batch_size: <integer>
timeout: <integer>
request_timeout: <integer>
max_bytes: <integer>
field_format: <string>
debug:
status: <boolean>
dont_send_logs: <boolean>

Configuration

The following fields are used to define the target:

FieldRequiredDefaultDescription
nameYTarget name
descriptionN-Optional description
typeYMust be gcpsecops
pipelinesN-Optional post-processor pipelines
statusNtrueEnable/disable the target

API Configuration

FieldRequiredDefaultDescription
api_versionNv2API version: v1, v2
send_events_asNunstructuredData format: unstructured, udm
udm_typeN*logsUDM submission type: logs, entities
regionY-SecOps ingestion region. See Regions below
customer_idY*-Google SecOps customer ID
max_bytesN1048576 (1 MB) for unstructured, 4194304 (4 MB) for udmMaximum size of a single request body or batch, in bytes. A value above the maximum the endpoint documents is clamped back to it
note

max_bytes caps the size of a single request body or batch. It behaves differently from max_size on the file-writing targets, and the difference is easy to get wrong:

  • An explicit max_bytes: 0 IS honoured and removes the ceiling on targets that have no ceiling of their own. The value is read with Int64, which returns what you wrote — unlike max_size, which is read with MustInt64 and silently substitutes its default for a zero. Where a target has a fixed ceiling of its own, its page says so and a zero is clamped to that ceiling instead.
  • A negative value is rejected at configuration time with max_bytes must not be negative.

The ceiling is validated when the target is built and enforced again on every batch, so a value the receiving service will refuse fails early rather than per request.

* = Conditionally required. udm_type applies when send_events_as: udm with V2 API. customer_id is required for V2 API.

Authentication

FieldRequiredDefaultDescription
authentication_methodNcredentialsAuthentication method: credentials, secret, apikey, apikeysecret
service_account_credentialsY*-Inline JSON service account credentials
service_account_credentials_secretY*-Service account JSON supplied through a reference such as ${VAR}, $env{VAR} or $secret{store=...,ref=...}. The reference must resolve to the JSON itself, not to the name of a variable
api_keyY*-Inline API key (V1 only)
api_key_secretY*-API key supplied through a reference such as ${VAR}, $env{VAR} or $secret{store=...,ref=...} (V1 only). The reference must resolve to the key itself

* = Conditionally required. The applicable field depends on authentication_method: credentialsservice_account_credentials; secretservice_account_credentials_secret; apikeyapi_key (V1 only); apikeysecretapi_key_secret (V1 only).

Unstructured Log Configuration

FieldRequiredDefaultDescription
default_log_typeY*-Default log type name
log_text_fieldN-Field name to use as log text. If empty, entire JSON event is used
namespaceN-SecOps namespace for log organization
custom_log_typesN-Array of custom log type definitions
custom_log_types[].log_typeY-Log type name
custom_log_types[].descriptionN-Log type description

* = default_log_type is required when send_events_as: unstructured (the default).

Labels

FieldRequiredDefaultDescription
labelsN-Array of custom labels to attach to events
labels[].keyY-Label key
labels[].valueY-Label value

Batch Configuration

FieldRequiredDefaultDescription
batch_sizeN1000Maximum events per batch
timeoutN30Request timeout in seconds
request_timeoutN30HTTP client timeout in seconds

Processing

FieldRequiredDefaultDescription
field_formatN-Data normalization format. See applicable Normalization section

Scheduling

See Scheduling and Pool Behavior for interval and cron fields shared by all targets.

Debug Options

FieldRequiredDefaultDescription
debug.statusNfalseEnable debug logging
debug.dont_send_logsNfalseProcess logs but don't send to target (testing)

Details

Data Sending Options

DataStream supports two approaches for submitting events to Google SecOps:

Unstructured Logs:

  • Send raw log data to SecOps
  • SecOps applies built-in parsers to convert logs into UDM format
  • Simpler configuration requiring only default_log_type
  • SecOps handles parsing and normalization
  • May encounter parsing issues with proprietary or uncommon log formats
  • Best for standard log types with existing SecOps parser support

Pre-Structured UDM Events:

  • Transform data into UDM format before sending
  • Bypass SecOps parsing entirely
  • Complete control over UDM field mapping
  • Requires understanding of UDM schema structure
  • Eliminates parsing errors and inconsistencies
  • Best for custom data sources or precise field control

The choice between approaches depends on data complexity and control requirements. Unstructured logs offer simpler setup with SecOps-managed parsing. Pre-structured UDM provides precision but requires upstream transformation.

Working with Unstructured Data

When using send_events_as: unstructured, log type assignment follows a hierarchical resolution:

Log Type Assignment Hierarchy:

  1. Event-level override: Events with __logType field use that value
  2. Default assignment: Events without __logType use default_log_type configuration
  3. Custom log types: Use custom_log_types array for unsupported or deprecated types

Standard Log Types:

SecOps maintains a dynamic list of supported log types (e.g., FIREWALL_LOG, WINDOWS_EVENT, SYSLOG). The supported types evolve over time as SecOps adds new parsers and deprecates old ones.

For the complete list of supported default parsers, see Google SecOps Parser List.

Custom Log Type Definition:

For log sources without SecOps parser support, define custom log types:

custom_log_types:
- log_type: PROPRIETARY_APP_LOG
description: Internal application security logs
- log_type: LEGACY_FIREWALL
description: Deprecated firewall format

Custom log types bypass standard SecOps parsing. Events are stored but may require custom SecOps rules for analysis.

Log Text Field Selection:

By default, the entire JSON event is sent as log text. Use log_text_field to extract a specific field:

log_text_field: message # Send only the 'message' field content

This is useful when the raw log text exists in a specific field while other fields contain metadata.

Regions

Valid SecOps ingestion regions:

Region CodeLocation
usUnited States
europeEurope (multi-region)
northamerica-northeast2Toronto, Canada
southamerica-east1S�o Paulo, Brazil
europe-west2London, UK
europe-west3Frankfurt, Germany
europe-west6Zurich, Switzerland
europe-west9Paris, France
europe-west12Turin, Italy
europe-central2Warsaw, Poland
africa-south1Johannesburg, South Africa
asia-northeast1Tokyo, Japan
asia-south1Mumbai, India
asia-southeast1Singapore
asia-southeast2Jakarta, Indonesia
australia-southeast1Sydney, Australia
me-central1Doha, Qatar
me-central2Dammam, Saudi Arabia
me-west1Tel Aviv, Israel
turinTurin, Italy (alias for europe-west12)
zurichZurich, Switzerland (alias for europe-west6)

API Version Selection

V2 API (Recommended):

  • Requires customer_id field
  • Supports unstructured logs and UDM
  • Regional endpoint support
  • Enhanced entity submission

V1 API:

  • API key authentication supported
  • Legacy endpoint compatibility
  • Limited to unstructured logs and UDM events

Authentication Methods

Service Account (OAuth2):

  • credentials: Inline JSON service account
  • secret: Service account JSON resolved from a ${VAR}, $env{VAR} or $secret{...} reference

API Key (V1 only):

  • apikey: Inline API key
  • apikeysecret: API key resolved from a ${VAR}, $env{VAR} or $secret{...} reference
Service Account Permissions

Service account requires the Chronicle API Writer role or equivalent permissions to ingest data into SecOps.

Data Format Options

Unstructured Logs:

  • Raw log text submission
  • Requires default_log_type field
  • Optional custom log types for classification
  • Best for text-based logs or pre-formatted data

UDM (Unified Data Model):

  • Structured event submission using SecOps UDM schema
  • Use udm_type: logs for security events
  • Use udm_type: entities for entity context (V2 only)
  • Requires events in UDM format
UDM Format Requirements

When using send_events_as: udm, ensure events conform to Google SecOps UDM schema. Invalid UDM events will be rejected.

Dynamic Field Overrides

Events can override target settings using reserved fields:

  • __logType: Override default log type per event
  • __namespace: Override namespace per event

These fields are read as overrides, but they are not stripped from the event. They remain in the submitted log text, so remove them in a pipeline if they must not reach SecOps.

Examples

Basic V2 Unstructured

Sending unstructured logs to SecOps V2 API, with the service account JSON read from an environment variable reference...

targets:
- name: secops-unstructured
type: gcpsecops
properties:
region: us
api_version: v2
send_events_as: unstructured
customer_id: "${SECOPS_CUSTOMER_ID}"
default_log_type: FIREWALL_LOG
authentication_method: secret
service_account_credentials_secret: "${GCP_SECOPS_CREDENTIALS}"

V2 with UDM Events

Forwarding UDM-formatted security events to SecOps using inline service account credentials...

targets:
- name: secops-udm
type: gcpsecops
properties:
region: europe
api_version: v2
send_events_as: udm
udm_type: logs
customer_id: "${SECOPS_CUSTOMER_ID}"
authentication_method: credentials
service_account_credentials: |
{
"type": "service_account",
"project_id": "your-project-id",
"private_key_id": "key-id",
"private_key": "-----BEGIN PRIVATE KEY-----\n...",
"client_email": "secops@your-project.iam.gserviceaccount.com"
}

V1 with API Key

Using V1 API with API key authentication, with the key read from an environment variable reference...

targets:
- name: secops-v1
type: gcpsecops
properties:
region: us
api_version: v1
send_events_as: unstructured
default_log_type: CUSTOM_LOG
authentication_method: apikeysecret
api_key_secret: "${SECOPS_API_KEY}"

With Custom Log Types

Defining multiple custom log types for different Windows event categories...

targets:
- name: secops-custom-types
type: gcpsecops
properties:
region: us
api_version: v2
send_events_as: unstructured
customer_id: "${SECOPS_CUSTOMER_ID}"
default_log_type: WINDOWS_EVENT
custom_log_types:
- log_type: WINDOWS_SECURITY
description: Windows security event logs
- log_type: WINDOWS_SYSTEM
description: Windows system event logs
- log_type: WINDOWS_APPLICATION
description: Windows application event logs
authentication_method: secret
service_account_credentials_secret: "${GCP_SECOPS_CREDENTIALS}"

With Namespace and Labels

Organizing logs with namespace and custom labels for production environment tracking...

targets:
- name: secops-labeled
type: gcpsecops
properties:
region: europe-west2
api_version: v2
send_events_as: unstructured
customer_id: "${SECOPS_CUSTOMER_ID}"
default_log_type: NETWORK_LOG
namespace: production
labels:
- key: environment
value: production
- key: datacenter
value: eu-west-1
- key: application
value: firewall
authentication_method: secret
service_account_credentials_secret: "${GCP_SECOPS_CREDENTIALS}"

With Log Text Field

Extracting specific field as log text instead of submitting entire JSON structure...

targets:
- name: secops-text-field
type: gcpsecops
properties:
region: us
api_version: v2
send_events_as: unstructured
customer_id: "${SECOPS_CUSTOMER_ID}"
default_log_type: SYSLOG
log_text_field: message
authentication_method: secret
service_account_credentials_secret: "${GCP_SECOPS_CREDENTIALS}"

V2 UDM Entities

Submitting entity context data using V2 UDM entities endpoint...

targets:
- name: secops-entities
type: gcpsecops
properties:
region: us
api_version: v2
send_events_as: udm
udm_type: entities
customer_id: "${SECOPS_CUSTOMER_ID}"
authentication_method: secret
service_account_credentials_secret: "${GCP_SECOPS_CREDENTIALS}"

Production Configuration

Production-ready configuration with custom log types, labels, and performance tuning...

targets:
- name: secops-production
type: gcpsecops
properties:
region: us
api_version: v2
send_events_as: unstructured
customer_id: "${SECOPS_CUSTOMER_ID}"
default_log_type: SECURITY_EVENT
namespace: production
log_text_field: raw_log
batch_size: 1000
timeout: 30
custom_log_types:
- log_type: AUTH_SUCCESS
description: Successful authentication events
- log_type: AUTH_FAILURE
description: Failed authentication attempts
- log_type: POLICY_VIOLATION
description: Security policy violations
labels:
- key: tenant
value: enterprise
- key: compliance
value: pci-dss
authentication_method: secret
service_account_credentials_secret: "${GCP_SECOPS_CREDENTIALS}"
debug:
status: false

Troubleshooting

This section covers the errors you are most likely to see with the gcpsecops target, what causes each one, and how to fix it.

Where to look:

  • Director logs. Target errors are tagged with the target name and carry "Section":"SenderPool". The part after Reason:, or after the last colon, is the actual cause.
  • The target's connection status in the web interface. It shows the same reason as the log line, prefixed with connection failed for <target name>:.

See Target Delivery Errors for how Director logs and retries target failures.

Which permission is missing?

Match the error you see against this table first.

Error textWhat is missingWhere it applies
secops api returned status 403, whose body typically names PERMISSION_DENIEDAuthorization for the service account to ingest into the SecOps tenant, or the ingestion API is not enabled for the projectThe tenant identified by customer_id
secops api returned status 401 with authentication_method: credentials or secretA service account key the ingestion API still accepts. Deleted and disabled keys fail hereThe key in service_account_credentials or service_account_credentials_secret
secops api returned status 401 or 403 with authentication_method: apikey or apikeysecretA valid, unrestricted ingestion API key issued for this tenantThe value of api_key or api_key_secret
failed to get oauth2 token: oauth2: cannot fetch token: 400 Bad RequestA key Google will still exchange for a token. This is checked before any permission isThe service account key itself

There is no single role name to check against. What the ingestion API requires is that the identity you configured is authorized to ingest into the tenant named by customer_id: either a service account your Google SecOps administrator has granted an ingestion role, or an ingestion API key issued for that tenant. Google decides this at its end, and the role name differs between Google SecOps editions, so treat Authentication Methods above as the reference for what to set up, rather than any role name quoted in an error message. A 401 or a 403 is not fatal to your data: the batch is redelivered about every five seconds until the grant is in place, so fix it and the backlog drains on its own.

"service_account_credentials is required when using credentials authentication"

[Error] [director] [target-<target id>] [secops-unstructured] ValidateConfig failed for target "secops-unstructured": service_account_credentials is required when using credentials authentication

Cause: the authentication method was not found, so the target fell back to credentials, and no service_account_credentials value was set. The usual reason is a configuration that nests the method under an authentication block. That form is not read. The method is the flat property authentication_method, and the credential property sits beside it, directly under properties.

Fix: write both at the same level.

properties:
authentication_method: secret
service_account_credentials_secret: "${GCP_SECOPS_CREDENTIALS}"

The same mistake produces a different message for each method, so read the message to see which method the target actually resolved.

  • service_account_credentials_secret is required when using secret authentication
  • api_key is required when using apikey authentication
  • api_key_secret is required when using apikeysecret authentication
  • invalid authentication_method: oauth, when the value is not one of credentials, secret, apikey or apikeysecret. The comparison is case sensitive.
  • api key authentication is only supported with v1 api, when apikey or apikeysecret is used without also setting api_version: v1

No data is lost. The target never starts, so nothing is sent and incoming events wait in the Director queue until the configuration is valid.

"failed to create credentials: invalid character ... looking for beginning of value"

Failed to reinitialize target "secops-unstructured" (attempt 1). Reason: failed to create credentials: invalid character 'G' looking for beginning of value

Cause: the value that reached the target is not service account JSON. The most common case is the name of an environment variable where its content was expected. GCP_SECOPS_CREDENTIALS is passed through unchanged and then parsed as JSON, which fails on its first letter. Two variants of the same problem are unexpected end of JSON input, when the reference resolved to an empty value, and missing 'type' field in credentials, when the JSON is valid but is not a service account key.

Fix: supply the key file content, either inline or through a reference that gets expanded: ${GCP_SECOPS_CREDENTIALS}, $env{GCP_SECOPS_CREDENTIALS} or $secret{store=my-store,ref=secops-key}. The resolved value must begin with { and contain "type": "service_account". Inline JSON has to keep the private_key newlines intact, so paste it as a YAML block scalar rather than as a single line.

No data is lost. The target retries initialization until the credential parses, and events queue in the meantime.

"failed to resolve service account credentials: credential: ..."

Failed to reinitialize target "secops-unstructured" (attempt 1). Reason: failed to resolve service account credentials: credential: env variable "GCP_SECOPS_CREDENTIALS" is not set

Cause: the reference is well formed but could not be resolved. credential: env variable "..." is not set means the variable is not exported to the Director process, which is not the same as being exported in your own shell. credential: store "..." not found in configuration and credential: secret with id "..." not found mean the $secret{...} token points at a store or an entry that does not exist.

Fix: export the variable in the service environment and restart Director so it inherits it, or correct the store name and the reference. The same wording appears as failed to resolve service account credentials secret, failed to resolve api key and failed to resolve api key secret for the other three methods.

No data is lost. Initialization is retried until the reference resolves.

"failed to get oauth2 token"

Failed to reinitialize target "secops-udm" (attempt 4). Reason: failed to get oauth2 token: oauth2: cannot fetch token: 400 Bad Request

Cause: Google refused to exchange the service account key for a token. Google's response follows on the next line and typically names invalid_grant, which usually means the key was deleted or disabled, or the host clock has drifted. A damaged key fails differently, with private key should be a PEM or plain PKCS1 or PKCS8 or private key is invalid, which points at private_key newlines lost while pasting.

Fix: issue a new key for the service account and put its content in the target, check the Director host clock against a time source, and allow outbound HTTPS to oauth2.googleapis.com on port 443. The same text appears later as Finalize failed on flush ... failed to get oauth2 token when a key is revoked while the target is running, because the token is refreshed about once an hour.

No data is lost. Events queue while the target retries, and the queue drains once a token is issued.

"secops api returned status 401" or "secops api returned status 403"

Sender worker 0 Finalize failed on flush for target "secops-production": secops api returned status 403: <the response body Google returned>

Cause: the target authenticated and reached the ingestion API, but Google refused the request. A 403 body typically names PERMISSION_DENIED and means the identity is not authorized for this tenant, or the ingestion API is not enabled. A 401 means the credential itself was rejected. One case sends no credential at all: when api_key_secret resolves to an empty value, the request goes out unauthenticated and 401 repeats forever with nothing else in the logs.

Fix: work through Which permission is missing? above, then confirm that customer_id is the tenant the credential belongs to. With apikeysecret, check that the secret resolves to a non-empty value.

No data is lost. The batch is redelivered about every five seconds until Google accepts it, so expect the queue to grow until the grant is fixed.

"record rejected by target: secops api returned status 400"

Sender worker 1 Finalize failed on flush for target "secops-udm": record rejected by target: secops api returned status 400: <the response body Google returned>
Sender worker 1 dropping <payload> for target "secops-udm" after 4 rejected flush attempts — the endpoint refuses this batch deterministically, so its records are given up on

Cause: Google rejected the batch itself, not the credential. Statuses 400, 413 and 422 are treated as permanent. Typical causes are a default_log_type or __logType value SecOps has no parser for, UDM events that do not match the SecOps schema, and a customer_id that is not the tenant identifier. A customer_id written as ${SECOPS_CUSTOMER_ID} with the variable unset passes the configuration checks and is then sent as that literal text, which lands here.

Fix: check the log type against the Google SecOps Parser List, validate UDM events against the SecOps schema before sending, and confirm customer_id and every ${...} reference on the Director host.

Data is lost here. The whole batch is given up on after four delivery attempts, and the drop line above is the only record of it.

"record size ... exceeds configured max_bytes ..."

Sender worker 3 deterministic failure for secops-unstructured after 4 attempts — dropping (giving up): record rejected by target: record size 1205311 exceeds configured max_bytes 1048479

Cause: a single event, once encoded, is larger than the room left in one request body. The second number is smaller than the value you configured because the request envelope is measured and subtracted first. The ceiling follows the maximum Google documents for the endpoint, typically 1 MB for unstructured log entries and 4 MB for UDM.

Fix: trim the event in a pipeline before it reaches the target, or switch to send_events_as: udm, where the larger ceiling applies. Raising max_bytes past the maximum does not help. It is clamped back, with a warning at startup that says the value exceeds the ...-byte maximum this endpoint documents and was clamped to it. Setting it very low fails at startup instead, with max_bytes must exceed the 97-byte secops request envelope, got 64.

Only the oversized event is lost, after four delivery attempts. The rest of the batch is delivered normally.

"secops api returned status 429"

Sender worker 0 execute() failed for secops-v1: secops api returned status 429: <the response body Google returned>

Cause: Google is throttling ingestion for the tenant. The body typically names RESOURCE_EXHAUSTED. Statuses 408 and 5xx behave the same way and usually mean a transient problem at Google's end.

Fix: nothing has to change in the target, which applies no rate limiting of its own. If 429 persists for hours rather than minutes, ask your Google SecOps administrator to review the ingestion quota for the tenant, and lower the volume routed to this target until it is raised.

No data is lost. Batches are redelivered about every five seconds until they are accepted.

"failed to send request", certificate errors, and timeouts

Sender worker 2 execute() failed for secops-labeled: failed to send request: Post "https://europe-west2-malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate": tls: failed to verify certificate: x509: certificate signed by unknown authority

Cause: Director could not complete the HTTPS call. The text after the URL names the layer that failed. no such host is DNS. connection refused and i/o timeout are a firewall. x509: certificate signed by unknown authority is a TLS inspecting proxy presenting its own certificate. proxyconnect tcp is a proxy that is configured but unreachable. context deadline exceeded and Client.Timeout exceeded while awaiting headers are the configured timeouts.

Fix: allow outbound HTTPS on port 443 from the Director host to two names, not one: the region ingestion host shown in the error, and oauth2.googleapis.com for the token. Add a TLS inspecting proxy's certificate authority to the operating system trust store, because this target reads no certificate authority setting of its own. Set HTTP_PROXY, HTTPS_PROXY and NO_PROXY for the Director service if a proxy is required. Raise timeout and request_timeout together, since the shorter of the two wins.

warning

Startup only contacts the token host. A host that can reach oauth2.googleapis.com but not the ingestion host reports a healthy connection and fails on the first flush instead, so do not read a green connection status as proof that delivery works.

No data is lost. Delivery is retried until the network path is open.

"invalid region", "customer_id is required for v2 api", and other rejected settings

ValidateConfig failed for target "secops-unstructured": invalid region: eu

Cause: a setting did not pass validation. Values are compared case sensitively, and an unset ${...} reference survives as literal text, which is why a missing variable often shows up as an invalid value rather than as an empty one.

Error textFix
region is required or invalid region: euUse a code from Regions, such as us, europe or europe-west2
customer_id is required for v2 apiSet customer_id, and make sure any ${...} reference is exported on the Director host
default_log_type is required when sending unstructured dataSet default_log_type, for example SYSLOG. It is required whenever send_events_as is left at unstructured
invalid api_version: v3Use v1 or v2
invalid send_events_as: UDMUse unstructured or udm, in lower case
invalid udm_type: entityUse logs or entities
batch_size must be greater than 0, got -5Remove the setting to get the default of 1000, or set a positive value
max_bytes must not be negative, got -1Remove the setting, or set a positive value

No data is lost. The target is not started until the configuration is valid, and events wait in the queue.

The target is healthy but the data in SecOps is wrong or missing

Work through these in order. None of them produces an error line.

  1. debug.dont_send_logs is enabled. Events are processed by the pipeline and never sent. With debug.status also enabled, startup logs Log sending is disabled for this target (secops-unstructured). Logs will be processed by the pipeline but will not be sent to the target. Nothing else marks the loss. Remove the flag.
  2. Plain text arrives unreadable. Without log_text_field, a record that is not JSON is wrapped in a JSON object whose value is encoded, so the SecOps parser never sees the original line. Set log_text_field: message for plain text sources such as syslog.
  3. Everything lands under one unexpected log type. When custom_log_types is configured and an event carries no __logType, every entry is tagged with the first entry in that list rather than with default_log_type. Remove custom_log_types unless that override is what you want, or set __logType per event in a pipeline.
  4. log_text_field names a field the events do not have. The whole JSON event is used as the log text instead, silently. Field names are case sensitive.
  5. Entities are stored as events. With api_version: v1, udm_type: entities is not rejected and the data is submitted to the events endpoint. Use api_version: v2 for entities.
  6. A label or a custom log type disappeared. Entries in labels with an empty key or value, and entries in custom_log_types with an empty log_type, are skipped without a message.
  7. __logType and __namespace show up in the data. They are read as overrides but are also left in the submitted log text. Strip them with a remove processor in a pipeline if they must not reach SecOps.
  8. A literal ${...} appears in SecOps. An unset reference in customer_id, default_log_type or namespace is sent as written. In customer_id it ends as a rejected batch instead.
tip

Dropped batches do not move a counter of their own. The dropping ... after 4 rejected flush attempts and deterministic failure ... dropping (giving up) lines in the Director log are the only trace, so alert on those two phrases if you need to know when data is discarded.