3 Crontab Mistakes AWS EventBridge Decoders Always Fix
The Linux Server on the Shelf vs. The Lambda in the Cloud
Last March, I had a crontab file with 47 lines on a single EC2 box. Today, that same box is decommissioned, and those 47 jobs run as AWS EventBridge schedules triggering Lambda functions. The migration took me three weeks. Not because the logic was hard — but because translating standard Unix crontab expressions to AWS EventBridge schedule syntax is full of silent traps that only surface at 2 AM when the wrong job fires.
If you're standing where I stood, staring at a crontab -l output and wondering why 30 2 * * 1-5 doesn't just paste cleanly into an EventBridge rule, this article is for you. I'll walk you through one real migration example — a nightly database snapshot job — and show you exactly where the syntax diverges, why it matters, and how a cron decoder tool saves you from guessing.
Five Fields vs Six Fields: The First Wall You Hit
What Unix Crontab Gives You
Standard Unix crontab uses five fields: minute, hour, day-of-month, month, and day-of-week. Our example job — a database snapshot that runs at 2:30 AM, Monday through Friday — looks like this on the Linux side:
30 2 * * 1-5 /opt/scripts/db_snapshot.sh
Clean. Five fields. The asterisk on day-of-month means "every day," and 1-5 on day-of-week means Monday through Friday. The script path is appended after the schedule. You've probably written hundreds of these.
What AWS EventBridge Expects Instead
AWS EventBridge cron expressions use six fields. The sixth field is year, and it's mandatory. Here's the same schedule in EventBridge syntax:
cron(30 2 ? * MON-FRI *)
Notice three things immediately changed: the year field appeared at the end, the day-of-month switched from * to ?, and 1-5 became MON-FRI. Each of those changes has a reason, and getting any one of them wrong means your job either doesn't fire or fires on the wrong day.
Numeric Day-of-Week: When 1 Means Monday in One World and Sunday in Another
The Unix Convention (Familiar, Predictable)
In Unix crontab, day-of-week numbering is 0-7, where both 0 and 7 represent Sunday. So 1-5 cleanly maps to Monday through Friday. I've been using this mapping for over a decade. It's muscle memory.
The AWS EventBridge Convention (Shifted by One)
AWS EventBridge uses 1-7, where 1 is Sunday and 7 is Saturday. So if you naively copy 1-5 into EventBridge, you're actually scheduling Sunday through Thursday — not Monday through Friday. That's a one-day shift that will quietly break your schedule.
Here's the correct numeric translation: Monday through Friday in EventBridge is 2-6. But honestly, I recommend using the named equivalents — MON-FRI — because it removes all ambiguity. When I was migrating those 47 jobs, I converted every numeric day-of-week to its three-letter name. It made the review process faster and eliminated the off-by-one bug class entirely.
The Question Mark Rule: Why * Becomes ?
When Asterisks Work Fine (Unix Side)
In Unix crontab, using * for both day-of-month and day-of-week means "either condition matches." If you write 30 2 * * 1-5, the job runs at 2:30 AM every day, but the day-of-week restriction 1-5 narrows it to weekdays. The two fields operate with an implicit OR relationship when both are restricted, and an unrestricted field (*) simply passes through.
When Asterisks Break Things (AWS Side)
AWS EventBridge doesn't allow you to use * for both day-of-month and day-of-week simultaneously if one of them is restricted. You must use ? for the field you want to ignore. The ? character specifically means "I don't care about this field, defer to the other one."
So our example goes from 30 2 * * 1-5 to cron(30 2 ? * MON-FRI *). The day-of-month becomes ? because we're specifying the day-of-week. If we were specifying the day-of-month instead — say, "run on the 15th of every month" — the day-of-week would become ?.
This was the single most common error I made during migration. I'd paste a crontab line, forget the question mark, and EventBridge would reject the rule with a validation error. AWS doesn't quietly accept it — the API throws an error — but if you're creating rules through CloudFormation or Terraform, the failure might not surface until deploy time.
Using a Cron Decoder to Bridge the Gap
After manually converting about a dozen expressions and making two off-by-one errors on day-of-week, I stopped trusting myself and started using a cron decoder. A cron decoder is a tool that takes a standard Unix crontab expression, parses each field, and outputs the equivalent AWS EventBridge syntax with all the field-count, question-mark, and day-of-week adjustments applied automatically.
Here's how the decoder processed our example, step by step:
Input: 30 2 * * 1-5
Decoder logic:
- Minute
30→ passes through unchanged - Hour
2→ passes through unchanged - Day-of-month
*→ converts to?(because day-of-week is restricted) - Month
*→ passes through unchanged - Day-of-week
1-5→ shifts to2-6numerically, or converts toMON-FRIby name - Year field → appended as
*
Output: cron(30 2 ? * MON-FRI *)
The decoder handles the three trap areas — field count, question mark substitution, and day-of-week offset — in one pass. For my 47-job migration, I ran each crontab line through the decoder, pasted the output into my Terraform module, and then did a manual review. The decoder caught what my muscle memory missed.
A Second Worked Example: The Monthly Report Job
Let me give you one more example from the same migration, because the question mark rule flips depending on which day field you're restricting. We had a monthly report job that ran on the 1st of every month at 6 AM:
Unix crontab: 0 6 1 * * /opt/scripts/monthly_report.sh
Here, day-of-month is 1 and day-of-week is *. In EventBridge, the question mark goes on day-of-week instead:
AWS EventBridge: cron(0 6 1 * ? *)
Notice the flip. In the weekday job, ? sat in the day-of-month position. In the monthly job, ? sits in the day-of-week position. The rule is consistent: ? always goes in the field you're not restricting. But if you're converting dozens of these by hand, it's easy to put the question mark in the wrong spot when the pattern changes between jobs.
That's exactly where the cron decoder earns its keep. It reads the input expression, detects which day field is restricted, and places the ? in the correct position automatically. No pattern-matching fatigue, no copy-paste errors at 11 PM.
Practical Migration Workflow: What Actually Worked for Me
Here's the workflow I settled on after trial and error. I'm sharing it because the order matters:
- Export the crontab file with
crontab -l > jobs.txt. Clean it up — remove comments and environment variable lines. - Run each line through the cron decoder. Save the output in a spreadsheet with columns for the original expression, the EventBridge expression, and the script path.
- Review the day-of-week conversions manually. Even with the decoder, I recommend eyeballing every
MON-FRIorSAT-SUNoutput to confirm it matches the original intent. - Deploy through Infrastructure as Code. Whether you use Terraform, CloudFormation, or the AWS CLI, putting the EventBridge expressions in version control means you can diff them against future changes.
- Set up CloudWatch alarms on each rule. EventBridge doesn't tell you if a Lambda failed — you need a separate alarm. This isn't syntax-related, but it's the most common gap I see in crontab-to-EventBridge migrations.
That five-step process took my migration from "three weeks of trial and error" to something I could now repeat in an afternoon. The cron decoder is the linchpin. Without it, step 2 becomes a manual translation exercise where every expression is a potential bug.
The Bigger Picture: Why This Translation Matters
Moving from Linux crontab to AWS EventBridge isn't just a syntax change — it's a shift from "a script on a box" to "a scheduled event in a distributed system." The crontab expression is the contract between your old world and your new one. Get the translation wrong, and you've got a job firing on Sunday instead of Monday, or not firing at all because EventBridge rejected the rule.
The good news is that the differences are finite and well-defined. Six fields instead of five. Question marks instead of asterisks for ignored day fields. Day-of-week shifted by one if you use numbers, or eliminated entirely if you use names. Once you internalize those three rules — or better yet, let a cron decoder apply them for you — the migration becomes mechanical.
That database snapshot job I mentioned at the start? It's been running on EventBridge for nine months now. cron(30 2 ? * MON-FRI *). Every weekday at 2:30 AM, the Lambda fires, the snapshot gets created, and I get a notification. No drift, no surprises. That's the payoff for getting the syntax right the first time.
Frequently Asked Questions
How do I convert a Unix crontab expression to AWS EventBridge schedule syntax?
To convert a standard Unix crontab expression to AWS EventBridge syntax, you need to add a sixth field for the year and replace asterisks in either the day-of-month or day-of-week field with a question mark (?). Using an online cron decoder tool automates this process, ensuring your expression meets AWS requirements without manual errors.
What is the difference between standard Unix cron and AWS EventBridge cron?
Standard Unix cron uses five fields (minute, hour, day-of-month, month, day-of-week), while AWS EventBridge requires six fields, adding a mandatory year field. Additionally, AWS EventBridge enforces a strict rule where you cannot use an asterisk (*) in both the day-of-month and day-of-week fields; one must be a question mark (?).
How does a cron decoder help with AWS EventBridge schedules?
A cron decoder translates complex Unix cron expressions into human-readable text while simultaneously formatting them for specific platforms like AWS EventBridge. It automatically handles syntax differences, such as adding the year field and replacing conflicting day indicators, saving you time during cloud infrastructure setup.
Why is my cron expression failing in AWS EventBridge?
Your cron expression is likely failing because it uses standard Unix 5-field syntax instead of the required 6-field AWS EventBridge syntax. Another common reason is using an asterisk in both the day-of-month and day-of-week fields, which AWS restricts—you must use a question mark (?) in one of them.
Can AWS EventBridge use standard 5-field cron expressions?
No, AWS EventBridge does not support standard 5-field Unix cron expressions and requires a 6-field format. You must convert your standard cron expression by appending a year field (or an asterisk for every year) and adjusting the day fields according to AWS syntax rules.
What does the question mark (?) mean in AWS EventBridge cron syntax?
In AWS EventBridge cron syntax, the question mark (?) is used as a wildcard for either the day-of-month or day-of-week field, indicating 'no specific value'. AWS requires you to use a question mark in one of these fields if you specify a value in the other, preventing conflicting schedule rules.
How do I convert a 5-field cron to a 6-field cron for AWS?
To convert a 5-field cron to a 6-field cron for AWS, simply append an asterisk (*) as the sixth field to represent every year. You must also review the day-of-month and day-of-week fields, changing one to a question mark (?) if both are currently set to an asterisk.
Are AWS EventBridge cron expressions in UTC?
By default, AWS EventBridge evaluates cron expressions in the UTC time zone, unlike standard Unix cron which typically uses the server's local time. When using a cron decoder to convert your schedules, always remember to adjust your original timing from local time to UTC to ensure your events trigger correctly.
Is there a tool to translate Linux crontab to AWS EventBridge?
Yes, many online cron decoder and converter tools are specifically designed to translate Linux crontab syntax into AWS EventBridge format. These tools instantly validate your expression, add the required year field, and fix the day-of-week and day-of-month wildcards to meet AWS standards.