Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Logstash By James Joyner IV · · 9 min read

Logstash Error Guide: '_dateparsefailure' Tag on Events — Match Every Timestamp Format

Quick answer

Fix the '_dateparsefailure' tag in Logstash: understand the tag's meaning, align timezone and locale, and match multiple timestamp formats in one date filter.

  • #logstash
  • #logging
  • #troubleshooting
  • #errors
Free toolkit

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 date filter in Logstash exists to turn a textual timestamp inside your event into a real time value stored in @timestamp. When it cannot interpret the string you point it at, it does not stop the pipeline — it lets the event through but attaches a marker tag so you can find the failures downstream. That marker is _dateparsefailure.

You will see it as an entry in the event’s tags array once it reaches Elasticsearch or a stdout output:

{
  "@timestamp" => 2026-07-10T14:02:11.883Z,
  "message"    => "10/Jul/2026:09:02:07 -0500 GET /health 200",
  "log_time"   => "10/Jul/2026:09:02:07 -0500",
  "tags"       => [
    [0] "_dateparsefailure"
  ]
}

The critical detail that trips people up: _dateparsefailure is a tag, not a log line or an exception. Logstash does not raise it to logstash-plain.log on its own. It is a semantic signal added to the event itself, meaning “a date filter tried to parse a field and none of its patterns matched.” Because the event still flows through, the symptom is silent — your data lands in Elasticsearch with @timestamp set to the ingest time (the moment Logstash processed it) instead of the real event time carried in the log. Dashboards look fine until you notice every event clustered at the wrong minute.

Symptoms

  • Events arrive in Elasticsearch/Kibana with a _dateparsefailure value in the tags field.
  • @timestamp reflects when Logstash ingested the line, not when the event actually occurred, so time-series charts show a spike at ingest time rather than the true distribution.
  • A subset of events (often one host, one app version, or one locale) is tagged while the rest parse cleanly — a classic sign of mixed formats in a single stream.
  • Kibana’s time filter appears to “lose” old data because backfilled events all collapse onto the moment of replay.
  • Events are off by a fixed number of hours — a timezone, not a format, problem — but may or may not carry the tag depending on how the pattern was written.

Common Root Causes

  • Format string does not match the actual timestamp — the single most common cause. dd/MMM/yyyy:HH:mm:ss Z matches 10/Jul/2026:09:02:07 -0500, but a stray difference (two-digit vs. one-digit day, comma vs. dot for fractional seconds) causes a total miss.
  • Multiple timestamp formats in one stream — an app that emits ISO8601 in one code path and a syslog-style MMM d HH:mm:ss in another. A date filter with only one pattern tags every event from the other path.
  • Locale mismatch on month/day namesMMM and EEE are locale-sensitive. On a JVM with a non-English default locale, Jul or Wed fails to parse unless you set locale => "en".
  • Timezone assumptions — the source omits an offset (2026-07-10 09:02:07) and you did not set timezone, so Logstash assumes the server’s local zone. This shifts times rather than tagging them, but a mismatched offset token (Z vs. ZZ) can tag as well.
  • Fractional seconds / epoch confusion — using ISO8601 against a value that carries microseconds, or feeding an epoch-millis field to a text pattern instead of UNIX_MS.
  • Whitespace or extra characters — a trailing space, wrapping brackets, or a grok capture that grabbed more than the timestamp leaves the date filter with a string it cannot match.
  • Wrong source field — the match array names a field that is empty or absent on some events; a missing field is treated as a parse failure.

Diagnostic Workflow

Start by validating the config itself. Logstash ships a config-test mode that parses your pipeline without starting it — always run this before touching a live node:

# Quick syntax check of the whole configured pipeline
sudo -u logstash /usr/share/logstash/bin/logstash --config.test_and_exit \
  --path.settings /etc/logstash

# Or point at a single file you are iterating on
/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/apache.conf --config.test_and_exit

--config.test_and_exit only catches syntax errors, not semantic mismatches — a date filter with the wrong pattern is still valid syntax. To see the actual parse behavior, run a tiny pipeline against a stdin input with a stdout { codec => rubydebug } output and paste a failing line. Here is a realistic pipeline that reproduces and then fixes the problem:

input {
  file {
    path => "/var/log/apache2/access.log"
    start_position => "beginning"
    sincedb_path => "/dev/null"
  }
}

filter {
  grok {
    match => { "message" => "%{IPORHOST:clientip} .* \[%{HTTPDATE:log_time}\] \"%{WORD:verb} %{DATA:request}" }
  }

  # A single-pattern date filter that tags anything not matching HTTPDATE
  date {
    match  => [ "log_time", "dd/MMM/yyyy:HH:mm:ss Z" ]
    locale => "en"
    target => "@timestamp"
    tag_on_failure => [ "_dateparsefailure" ]
  }
}

output {
  stdout { codec => rubydebug }

  # Route only the failures to a file so you can inspect the raw timestamps
  if "_dateparsefailure" in [tags] {
    file { path => "/var/log/logstash/date-failures.log" }
  }
}

Run that pipeline and watch the rubydebug output: tagged events show you exactly which log_time string failed. Because you also fork failures to /var/log/logstash/date-failures.log, you get a corpus of the exact formats you are not yet handling. Then grep the main log for filter-level warnings:

grep -i 'dateparse\|_dateparsefailure' /var/log/logstash/logstash-plain.log
tail -f /var/log/logstash/date-failures.log

The fix is almost always to supply multiple patterns to the same date filter — the filter tries each in order and tags only if all miss:

date {
  match => [ "log_time",
             "dd/MMM/yyyy:HH:mm:ss Z",      # Apache/HTTPDATE
             "ISO8601",                      # 2026-07-10T09:02:07.883-05:00
             "MMM d HH:mm:ss",               # syslog, single-digit day
             "MMM  d HH:mm:ss",              # syslog, space-padded day
             "UNIX_MS" ]                     # epoch milliseconds
  locale   => "en"
  timezone => "America/Chicago"
  target   => "@timestamp"
}

Example Root Cause Analysis

A team ingested a single Filebeat stream that carried logs from two services behind the same ingress: a legacy Apache proxy and a new Go service. Kibana showed roughly 30% of events tagged _dateparsefailure, and those events all bunched onto the ingest minute.

The date filter had one pattern, dd/MMM/yyyy:HH:mm:ss Z, tuned for the Apache proxy. Forking failures to /var/log/logstash/date-failures.log revealed the untagged-in-Apache-but-tagged-in-Go strings looked like 2026-07-10T09:02:07.883-05:00 — RFC3339 from the Go service’s structured logger. One filter, two formats, so every Go line missed.

Two compounding issues surfaced. First, the Go timestamps were ISO8601 with fractional seconds, which the Apache pattern could never match. Second, when they naively added MMM d HH:mm:ss to catch some syslog lines, single-digit days (Jul 9) still failed because syslog space-pads to Jul 9 — two spaces. The final date filter listed all four real formats (dd/MMM/yyyy:HH:mm:ss Z, ISO8601, MMM d HH:mm:ss, and MMM d HH:mm:ss) plus locale => "en" because a subset of hosts ran with a German JVM locale that broke MMM. After deploying, the tag rate dropped to zero and @timestamp matched the real event times.

Prevention Best Practices

  • List every real format in one date filter. The filter is designed to try patterns in order; enumerate all the formats a stream can carry rather than assuming one.
  • Always set locale => "en" when a pattern uses MMM, MMMM, EEE, or EEEE, so a non-English JVM default cannot break month/day name parsing.
  • Set timezone explicitly whenever the source timestamp has no offset. Never rely on the Logstash server’s local zone — it drifts across environments.
  • Alert on the tag, don’t just ignore it. Add a Kibana/Watcher alert on tags: _dateparsefailure so a new log format is caught the day it ships, not months later.
  • Fork failures to a side channel (a file or a dead-letter index) during rollout so you can collect the exact strings you are missing.
  • Prefer structured logging at the source (JSON with an ISO8601 field) so the date filter has a single, unambiguous target — "ISO8601" handles it directly.

Quick Command Reference

# Validate pipeline syntax without starting Logstash
bin/logstash --config.test_and_exit --path.settings /etc/logstash

# Test a single config file
bin/logstash -f /etc/logstash/conf.d/apache.conf --config.test_and_exit

# Iterate on a pattern interactively: paste lines into stdin
echo '10/Jul/2026:09:02:07 -0500' | \
  bin/logstash -e 'input{stdin{}} filter{date{match=>["message","dd/MMM/yyyy:HH:mm:ss Z"] locale=>"en"}} output{stdout{codec=>rubydebug}}'

# Find date-parse failures already logged
grep -i 'dateparsefailure' /var/log/logstash/logstash-plain.log

# Count tagged events in Elasticsearch
curl -s 'localhost:9200/logs-*/_count' -H 'Content-Type: application/json' \
  -d '{"query":{"term":{"tags":"_dateparsefailure"}}}'

Conclusion

_dateparsefailure is not a crash — it is Logstash telling you, event by event, that a date filter’s patterns did not match the timestamp you asked it to read. Because the event still flows through with @timestamp set to ingest time, the damage is silent and shows up as time-series data landing in the wrong bucket. The cure is almost always to enumerate every real format the stream carries in a single date filter, pin the locale for name-based tokens, and set an explicit timezone when the source omits an offset. Validate with --config.test_and_exit, prove the fix with a stdin/rubydebug pipeline, and add an alert on the tag so the next new log format announces itself instead of hiding. For more filter and parsing fixes, see the other guides in the Logstash category.

Free download · 368-page PDF

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.