Telegraf Error Guide: '[processors.starlark] ... error in Starlark' — Fix Starlark Script Errors
Fix Telegraf's [processors.starlark] script error: repair the apply() function, handle None fields and types, avoid unsupported Python features, and debug metric mutation with telegraf --test.
- #telegraf
- #metrics
- #troubleshooting
- #errors
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
The starlark processor runs a small Python-like script against every metric. When the script raises at runtime, Telegraf logs the error with the file/line inside the Starlark source and drops the metric being processed:
2026-07-10T12:00:00Z E! [processors.starlark] Error in plugin: fields.star:7:23: in apply: unknown binding: cpu_total
Type errors are equally common — Starlark is strict about mixing types and about None:
E! [processors.starlark] Error in plugin: transform.star:12: unsupported binary op: float + NoneType
A script that fails to load at startup prevents Telegraf from starting at all, while a runtime error inside apply() drops individual metrics.
Symptoms
- Metrics that pass through the starlark processor are missing or unmodified, and the log shows
Error in plugin: <file>.star:<line>. - Telegraf fails to start entirely when the script has a load-time syntax error.
- Errors reference
apply,unknown binding,unsupported binary op, orNoneType. - The script works on some metrics but fails on others (those missing an expected field).
- Adding a new tag/field in Starlark silently produces nothing because
apply()returnedNone.
Common Root Causes
apply()does not return the metric — forgettingreturn metricdrops every metric silently.- Accessing a field/tag that may not exist —
metric.fields["cpu_total"]raisesunknown binding/key not foundwhen absent. - Type mismatches — arithmetic between a float field and a
None, or between a string and an int. - Using unsupported Python — Starlark has no
while, no recursion, noimport, no f-strings, and a limited stdlib; copied Python fails to load. - Mutating during iteration — changing
metric.fieldswhile iterating over it raises a runtime error. - Load-time syntax errors — indentation or a construct Starlark rejects, which blocks agent startup.
- Returning the wrong type —
apply()must return a metric, a list of metrics, orNone(to drop); anything else errors.
Diagnostic Workflow
Isolate the processor with a file input containing a representative sample so you can iterate quickly without live data:
# /tmp/starlark-test.conf
[[inputs.file]]
files = ["/tmp/sample.lp"]
data_format = "influx"
[[processors.starlark]]
script = "/etc/telegraf/scripts/transform.star"
[[outputs.file]]
files = ["stdout"]
printf 'cpu,host=web01 usage_user=12.5,usage_system=3.1\n' > /tmp/sample.lp
telegraf --config /tmp/starlark-test.conf --test --debug
Write defensive Starlark that guards missing fields and always returns the metric:
# /etc/telegraf/scripts/transform.star
def apply(metric):
u = metric.fields.get("usage_user")
s = metric.fields.get("usage_system")
# Guard against missing fields (None) before arithmetic
if u != None and s != None:
metric.fields["usage_busy"] = u + s
metric.tags["team"] = "platform"
return metric # MUST return the metric (or None to drop)
Reference the script from your real config and re-test the whole pipeline:
[[processors.starlark]]
script = "/etc/telegraf/scripts/transform.star"
Use the log module inside Starlark to trace values during development:
load("logging.star", "log") # available in recent Telegraf builds
def apply(metric):
log.debug("fields: {}".format(metric.fields))
return metric
Example Root Cause Analysis
A processor meant to compute a busy percentage worked in testing but flooded the log with unsupported binary op: float + NoneType in production. The script did metric.fields["busy"] = metric.fields["usage_user"] + metric.fields["usage_system"]. In the lab, every sample had both fields; in production, some hosts occasionally reported only usage_user (the other field was absent that interval), so metric.fields["usage_system"] returned None and the addition failed, dropping the metric.
The fix was to fetch fields with .get() and guard for None before arithmetic, exactly as shown in the diagnostic block above. After deploying the defensive version, the errors stopped and metrics with only one field passed through unmodified instead of being dropped. The lesson: Starlark scripts run against real, messy data where fields come and go — never assume a field exists, always use .get(), and always return metric.
Prevention Best Practices
- Always end
apply()withreturn metric(or an explicitNonewhen you intend to drop); a missing return silently drops everything. - Read fields and tags with
.get()and guard forNonebefore any arithmetic or string operation. - Test every script against a
fileinput with representative samples — including edge cases with missing fields — before deploying. - Remember Starlark is not Python: no
import, nowhile, no recursion, no f-strings; use.format()andload()for modules. - Never mutate
metric.fields/metric.tagswhile iterating over them; collect changes first, then apply. - Keep scripts small and pure; move complex logic upstream into the producing service where you have a full language.
Quick Command Reference
# Isolate the processor with a file input and sample metric
printf 'cpu,host=web01 usage_user=12.5\n' > /tmp/sample.lp
telegraf --config /tmp/starlark-test.conf --test --debug
# Validate the whole config after editing the script
telegraf --config /etc/telegraf/telegraf.conf --test --debug
# Watch Starlark runtime errors live
journalctl -u telegraf -f | grep -i starlark
# Confirm version (Starlark features vary by release)
telegraf --version
Conclusion
[processors.starlark] ... error in Starlark points at a script bug: a missing return metric, access to an absent field, a type mismatch with None, or unsupported Python. Isolate the processor with a file input and sample metrics, write defensively with .get() and None guards, and always return the metric. Because Starlark runs against real, variable data, testing against edge cases — not just the happy path — is what keeps the pipeline from silently dropping metrics.
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.