Where does the request stop?
Follow the packet. The Ignition gateway's OPC UA client builds a service request and hands it to the Eclipse Milo stack. The stack sends it over TCP to the third-party OPC UA server running in the PLC. The failure trace shows exactly where the path ends:
UaServiceFaultException: status=Bad_InvalidTimestamp, message=The timestamp is outside the range allowed by the server.
at org.eclipse.milo.opcua.stack.client.UaStackClient.lambda$deliverResponse$5(UaStackClient.java:337)
...
8.1.37 (b2024013011) Azul Systems, Inc. 17.0.9
The exception is raised inside deliverResponse. The client did not time out, so the server received the request, decoded it, and answered with a ServiceFault. Layer one, IP routing, the TCP port, and the secure channel all worked. The connection used SecurityPolicy=None, which rules out certificate exchange as the blocker. The rejection is an application-layer decision made by the server.
| Hop | Component | State |
|---|---|---|
| 1 | Ignition 8.1.37 gateway, Milo client stack, Azul Java 17.0.9 | Request built with gateway clock timestamp |
| 2 | Ethernet / IP / TCP to PLC endpoint | Delivered (response came back) |
| 3 | Secure channel, SecurityPolicy=None
|
Open, no certificate check involved |
| 4 | Server service layer in PLC | Rejects request: Bad_InvalidTimestamp
|
What is the server comparing the timestamp against?
Every OPC UA service request carries a RequestHeader, and that header includes a timestamp the client fills in from its own system clock at send time. A server can compare that value against its own clock and refuse any request that falls outside an acceptance window. When it does, it returns Bad_InvalidTimestamp with the text "The timestamp is outside the range allowed by the server." The check limits replayed or stale requests. The server implements the check and sets the width of the window. The client has no setting that disables it. Ignition cannot relax a limit the PLC enforces.
OPC UA DateTime values are UTC. Timezone and daylight-saving settings on the gateway or the PLC do not enter the comparison, provided each device converts local time to UTC correctly. The offset that matters is the absolute UTC difference. At this site the two clocks differed by about 10 minutes, and the difference was not a timezone offset. That real skew was enough to exceed the server's window.
Two details from this failure pattern explain behavior that otherwise looks random:
- It worked until yesterday. A PLC real-time clock with no time synchronization drifts steadily. The connection keeps working while the accumulated offset stays inside the window. On the day the drift crosses the limit, every request fails. Nothing on the Ignition side changed.
- The programmer's tool still connects. Engineering software usually talks to the controller over the vendor's native programming protocol, not through OPC UA sessions against this server, so the timestamp check never runs. It is also possible that the programming PC's clock sits closer to the PLC clock. In either case, a working engineering connection proves nothing about OPC UA time alignment.
Which symptoms separate clock skew from other OPC UA faults?
| Symptom | Likely cause | Deciding check |
|---|---|---|
ServiceFault Bad_InvalidTimestamp with SecurityPolicy=None
|
Client/server UTC clock skew beyond server window | Compare gateway UTC with PLC UTC to the second |
| Fault appears suddenly with no configuration change on either side | RTC drift crossed the tolerance threshold | Read PLC clock history or compare against NTP reference over a few days |
| Vendor engineering tool connects, Ignition does not | Different protocol path; no timestamp check on the tool's path | Connect a second OPC UA client from a host with a known-good clock |
| Fault persists after gateway restart or connection re-save | Server-side check, not client session state | Correct the clock, then retry |
| Certificate trust or validity errors instead of a timestamp fault | Security handshake problem; large skew can also make certificates look not-yet-valid | Inspect trusted/rejected certificate lists on both sides |
| Connection refused or timeout, no ServiceFault | Network, port, or endpoint URL problem | Ping, TCP port test, then endpoint discovery |
What options clear Bad_InvalidTimestamp?
Four approaches apply. A packet capture is a fifth tool, but it diagnoses the fault and does not fix it.
| Approach | Where applied | Durability | Side effects | Field result |
|---|---|---|---|---|
| Manually set the PLC clock to gateway time | PLC, via programming tool | Temporary; drift resumes immediately | None. Needs repeating as the clock drifts. | Cleared the fault at this site |
| Point gateway and PLC at the same NTP source | Gateway OS and PLC time settings | Permanent while NTP is reachable | PLC needs an NTP client and a network path to the time server (UDP 123) | Recommended long-term fix |
| Widen or disable the server's timestamp tolerance | Third-party server configuration, if exposed | Permanent | Weakens replay protection. Hides drift that still corrupts source timestamps. | Depends on server vendor. Check its manual. |
| Change an Ignition connection setting | Ignition gateway | n/a | No setting exists. The server enforces the check. | Not possible |
Wireshark capture with SecurityPolicy=None
|
Gateway NIC or mirrored switch port | Diagnostic only | Traffic is in cleartext during the test | Shows both timestamps and the failing request |
Which approach should be applied?
Set the PLC clock manually to recover the connection now. Then put both devices on a shared NTP source so the fault cannot come back. The manual sync proved the diagnosis here: once the programmer aligned the PLC clock with the gateway clock, the connection came up and data flowed normally. Without a synchronization source, the same drift will cross the threshold again.
Treat widening the tolerance as a last resort, even when the server allows it. The PLC clock also stamps the source timestamps on every value, event, and alarm it publishes. If the connection stays up while the clocks disagree by minutes, the historian stores values with wrong source times. Alarm sequences recorded by the PLC and by the gateway no longer line up. Disabling the check hides that problem instead of fixing it.
How do I bring the gateway and PLC clocks into sync?
- Check that the gateway's own clock is correct. On Windows, run
w32tm /query /statusand confirm a valid source and a recent successful sync. On Linux, runtimedatectland confirm the system clock is synchronized. If the gateway itself is wrong, syncing the PLC to it only moves the error. - Read the PLC's current date and time from the programming software or controller diagnostics. Note its configured timezone and convert both readings to UTC before comparing.
- Record the offset to the second, including its sign (PLC ahead or behind). This number is the baseline for the tolerance question and for tracking drift.
- Set the PLC clock to match the gateway (or the NTP reference) for immediate recovery.
- Configure the PLC's NTP client, if the controller has one, to use the same time server as the gateway. Open UDP 123 through any firewall between the PLC network and the time server.
- If the controller has no NTP client, schedule a periodic clock set through the controller's time-set mechanism. Make the interval short enough that drift never approaches the server window.
- Ask the server vendor for the name and value of the timestamp tolerance parameter. Record it next to the drift baseline so you know how much margin exists.
- Let the Ignition OPC UA connection reconnect on its retry cycle, or edit and save the connection to force an immediate reconnect.
How do I confirm the skew in a packet capture?
A capture is optional once the clocks are fixed. It is still the fastest way to prove the diagnosis before touching production clocks, or to measure the server window when the vendor documentation is thin.
- Keep the connection at
SecurityPolicy=Noneso the OPC UA payload is readable. With signing or encryption active, the headers are opaque. - Capture on the gateway NIC, or on a mirrored switch port facing the PLC. Filter on the TCP port from the endpoint URL. If the server uses a non-default port, use Wireshark's Decode As to apply the OPC UA dissector.
- Find the ServiceFault response. The request just before it names the service that failed, such as session creation, activation, or a later read or subscription call.
- Expand the failing request's RequestHeader and read its Timestamp. This value comes from the gateway's clock.
- Expand the ServiceFault's ResponseHeader and read its Timestamp. This value comes from the server's clock.
- Subtract the two. The result is the skew as the server sees it. It should match the offset measured in the previous procedure, within network latency.
Repeat the capture after adjusting the clocks in small steps. The offset at which requests start succeeding approximates the server's acceptance window. Use this method only if the vendor cannot give you the parameter value.
How do I verify the fix holds?
- Open the OPC connections status page on the Ignition gateway and confirm the third-party server shows Connected, with no
Bad_InvalidTimestampentries in the gateway logs after the reconnect. - Browse the server in the OPC Quick Client and read several tags. Confirm quality is Good and values update.
- Compare each value's source timestamp with gateway time. They should agree within seconds, not minutes.
- Restart the PLC, or cycle its network connection. Confirm the clock re-synchronizes and the Ignition connection returns to Connected without manual intervention.
FAQ
How do I fix Bad_InvalidTimestamp on an Ignition OPC UA connection?
Set the PLC or server clock to match the Ignition gateway's UTC time. The connection should recover on the next retry. To keep the fault from returning, point both devices at the same NTP server. Ignition has no setting that disables the check, because the server enforces it.
How do I tell whether a timezone mismatch causes Bad_InvalidTimestamp?
Convert both clocks to UTC and compare them. OPC UA timestamps are UTC, so a correctly configured timezone difference cancels out. A residual offset of minutes after conversion is real clock skew, and even about 10 minutes can exceed a server's window.
How do I increase the timestamp tolerance on a third-party OPC UA server?
Look for a timestamp tolerance or request-validation setting in the server's configuration or the PLC vendor's documentation. Not every server exposes one. Widening it hides clock drift that still corrupts source timestamps, so fix the clocks first.
Why does the PLC programming software still connect when Ignition gets Bad_InvalidTimestamp?
Programming tools usually use the vendor's native protocol instead of OPC UA sessions against the embedded server, so the timestamp check never runs. The programming PC's clock may also be closer to the PLC clock. Neither case shows that the OPC UA clocks are aligned.
How do I capture OPC UA request timestamps in Wireshark?
Set the connection to SecurityPolicy=None and capture on the gateway NIC, filtering on the endpoint's TCP port. Apply the OPC UA dissector, then compare the failing request's RequestHeader Timestamp with the ServiceFault's ResponseHeader Timestamp. The difference is the skew the server rejected.