influxdata/influxdb · error

invalid database name: {db_name}

Error message

invalid database name: {db_name}

What it means

After a plugin runs, handle_return_state writes back lines the plugin queued in PluginReturnState.write_db_lines. Each database name must pass DatabaseName::new, which allows only alphanumeric characters plus '/', '_', '-' and a length of 1..=511. An invalid name is collected as anyhow error 'invalid database name: {db_name}' (prefixed with invalid_database_name) while the remaining databases' lines are still processed — so writes to bad names are dropped, not retried.

Source

Thrown at influxdb3_processing_engine/src/worker/local.rs:559

            error!(error = %ErrorOneLine(error), ?self.trigger_definition, %context, "error running plugin");
        }
    }

    /// Handles the return state from the plugin, writing back lines and handling any errors.
    /// It returns a vec of error messages that can be used to log or report back to the user.
    async fn handle_return_state(
        &self,
        plugin_return_state: influxdb3_py_api::system_py::PluginReturnState,
    ) -> Vec<anyhow::Error> {
        let ingest_time = SystemTime::now()
            .duration_since(SystemTime::UNIX_EPOCH)
            .unwrap();

        let mut errors = Vec::new();

        for (db_name, lines) in plugin_return_state.write_db_lines {
            let Ok(database_name) = DatabaseName::new(db_name.clone()) else {
                errors.push(anyhow!("invalid database name: {db_name}"));
                continue;
            };

            if let Err(e) = self
                .write_endpoint
                .write_lp(
                    WriteTarget::User(database_name),
                    lines.join("\n").as_str(),
                    Time::from_timestamp_nanos(ingest_time.as_nanos() as i64),
                    false,
                )
                .await
                .with_context(|| format!("error writing back lines to {db_name}"))
            {
                errors.push(e);
            }
        }

View on GitHub (pinned to d28e26e048)

Solutions

  1. Sanitize the database name to [A-Za-z0-9_/-] before write_db_lines (e.g. re.sub(r'[^A-Za-z0-9_/-]', '_', db_name))
  2. Check length: 1..=511 characters
  3. Create the target database first with a valid name and reference that constant in the plugin

Example fix

# before
context.write_db_lines("tenant.acme corp", ["cpu v=1"])

# after
import re
safe = re.sub(r"[^A-Za-z0-9_/-]", "_", db_name)
context.write_db_lines(safe or "default_db", ["cpu v=1"])
Defensive patterns

Strategy: validation

Validate before calling

import re

_DB_NAME = re.compile(r"^[A-Za-z0-9_/-]{1,511}$")

def valid_db_name(name: str) -> bool:
    return bool(_DB_NAME.fullmatch(name))

if valid_db_name(db_name):
    context.write_db_lines(db_name, lines)
else:
    logger.warning("dropping lines for invalid db name %r", db_name)

Prevention

When it happens

Trigger: Python plugin calls context.write_db_lines(db_name, lines) (or LogWriter equivalent) with a name containing a space, dot, or other disallowed character, an empty string, or longer than 511 chars — e.g. write_db_lines('my db', ...) or a name derived from a user-supplied table/host string.

Common situations: Deriving the database name from untrusted input (table names, tenant names with dots like 'acme.corp'); assuming '.' is legal because it is common in other systems; names built by templating that can render empty.

Related errors


AI-assisted analysis of influxdata/influxdb@d28e26e048 (2026-08-16). Data as JSON: /api/errors/26d597a8a3a93f67. Report an issue: GitHub.