influxdata/influxdb · error · WriteError::InternalWriteUnsupported

internal writes are not supported by the write accumulator

Error message

internal writes are not supported by the write accumulator

What it means

WriteError::InternalWriteUnsupported is returned by the plugin WriteAccumulator's write_lp when a plugin attempts to write to the internal/system database (WriteTarget::Internal, or a User target naming the internal DB name) during plugin execution. Plugins may only accumulate writes into user databases; internal database writes are not supported in this context.

Solutions

  1. Change the plugin to write to a user database instead of the internal/system database
  2. Check where the target database name is computed/configured and ensure it never equals the internal DB name
  3. Move internal-metrics data to a dedicated user database if it must be written from a plugin
  4. If internal writes are genuinely required, perform them outside plugin execution via the normal write path/CLI

Example fix

// before (plugin)
api.write_to_database('_internal', line_protocol)
// after (plugin)
api.write_to_database('my_metrics_db', line_protocol)
Defensive patterns

Strategy: validation

Validate before calling

INTERNAL_DB = '_internal'

def guard_target(db):
    if not db or db == INTERNAL_DB:
        raise ValueError(f'plugin writes to internal database {db!r} are not allowed')

Type guard

def is_user_db(name):
    return isinstance(name, str) and len(name) > 0 and not name.startswith('_')

Try / catch

try:
    api.write_to_database(target_db, line_protocol)
except Exception as e:
    if 'internal writes are not supported' in str(e):
        target_db = 'fallback_user_db'
        api.write_to_database(target_db, line_protocol)
    else:
        raise

Prevention

When it happens

Trigger: A Python plugin calls the write endpoint (api.write_to_database or similar) targeting the internal database name (INTERNAL_DB_NAME), or the write machinery routes the write to WriteTarget::Internal while the plugin WriteAccumulator is the endpoint.

Common situations: Plugin code dynamically computes the target database name and accidentally resolves to the system/internal database; a plugin written for a context that allowed internal writes is reused in a trigger/plugin context where the accumulator forbids them; hardcoding the internal DB name in plugin configuration.

Related errors


AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19). Data as JSON: /api/errors/8f9cdcc5a620ecb0. Report an issue: GitHub.

Appendix: source

Thrown at influxdb3_py_api/src/write.rs:57

        match target {
            WriteTarget::User(database) if database.as_str() == INTERNAL_DB_NAME => {
                Err(WriteError::InternalWriteUnsupported)
            }
            WriteTarget::User(database) => {
                self.push(database.as_str().to_owned(), lp.to_owned());
                Ok(())
            }
            WriteTarget::Internal => Err(WriteError::InternalWriteUnsupported),
        }
    }
}

#[derive(Debug, Error)]
pub enum WriteError {
    #[error("Cannot write: {0}")]
    Fail(Box<dyn std::error::Error + Send + Sync>),

    #[error("internal writes are not supported by the write accumulator")]
    InternalWriteUnsupported,
}

#[derive(Debug, Clone)]
pub enum WriteTarget {
    /// Write into a user database.
    User(DatabaseName),
    /// Write into the one system-managed internal database.
    Internal,
}

#[async_trait]
pub trait WriteEndpoint: std::fmt::Debug + Send + Sync + 'static {
    async fn write_lp(
        &self,
        target: WriteTarget,
        lp: &str,
        ingest_time: Time,

View on GitHub (pinned to 06200ef96b)