Skip to main content

Technical Troubleshooting

Common symptoms / errors and their solutions. Quick classification → detailed resolution flow.

Diagnostic Resources for Container Mode (2026.05+)
  • status.sh — One-line summary of container + port + API + key app.properties
  • health.sh — Comprehensive health check based on exit codes (suitable for cron)
  • doctor.sh — Diagnostic tarball for support escalation (api / docker / systemd / 7 component logs / redacted config / host metrics)
  • /api/v1/system/health — Status map for 8 components + 503 branching (immediately identify which component is DOWN)
  • Container Mode Operations — Failure response + command cheat sheet

Symptom Index​

SymptomCandidate Cause
App stops during bootCassandra connection failure, DDL application failure
/api/v1/edge response is started=falseCollector initialization failure (driver / cache issue)
Specific OPC only connection_status=DISCONNECTEDPLC network / authentication / address format
All OPCs occasionally disconnect simultaneouslyFull restart of OPCUAServerManager due to OPC add/modify
MQTT publish not workingmqtt.enable=false or broker authentication failure
Sparkplug topic not publishedsparkplug.enable=false or missing jar
Screen loads slowlyopcList() N+1 queries + accumulated sleep
OPC startup takes 5 seconds eachThread.sleep impact (Phase A1 target)

Boot / Initialization​

Cassandra Connection Failure​

Caused by: com.datastax.oss.driver.core.exceptions.NoHostAvailableException
CheckWhat to Verify
Cassandra runningnodetool status
Port reachabilitytelnet <app.db.host> 9042
Keyspace existsAfter cqlsh -u cassandra -p cassandra, run DESCRIBE KEYSPACE pe;
app.db.* matches oltp.cassandra.*Review both entries in app.properties

app.sql.path has a typo in resouces​

The resouces in the app.sql.path = classpath:resouces/sql of app.properties has a typo, but it works because the directory is maintained with the same name. If you get an error saying SQL resources cannot be found, verify that the WEB-INF/resouces/sql/ path actually exists.


OPC / Drivers​

Specific OPC Connection Failed​

ProtocolFirst Check
OPCUAopc_agent_port reachability, try discovery=true, user/password
Modbus TCPPort 502 reachability, holding-register:... format
MELSECMC protocol active, controller-type=Q_L match
S7Rack/slot match, "PUT/GET" active
LSIf NetUtils.isReachable fails, suspect ICMP blocking, port 2004
EIPRack/slot, port 44818

Refer to the "Common Errors + Solutions" table on each driver page first.

LS-PLC Ping failed​

The LS driver checks reachability via ICMP ping before connecting. If ICMP is blocked on the corporate network, even a healthy PLC will be reported as failed.

Resolution:

  • Allow ICMP in the firewall
  • Or, disable the ping check via option in LSDriver.connect() in a future change (currently requires a code change)

32-bit / 64-bit Value Mismatch​

This is mostly caused by format not specified.

ProtocolIncorrect Pattern → Correct Pattern
LSD00600 + Integer (read as 16-bit) → D00600 + Integer + format=DW
Modbusholding-register:1 (16-bit) → holding-register:1:DINT
S7%DB1.DBW0 + Float → %DB1.DBD0 + format=REAL

32-bit Float Value is NaN / a Large Number​

This is a byte order (endianness) issue. Check the byte/word swap policy on the slave / master:

  • For Modbus, use PLC4j options such as :UDINT_LSWORD_FIRST
  • For other protocols, post-process with a formula

Transport (MQTT / Sparkplug)​

MQTT Publish Not Working​

# broker 도달 확인
MQTT_USER="${MQTT_USER:-edge}"
MQTT_PASSWORD="$(tr -d '\r\n' < /run/secrets/mqtt-password)"
mosquitto_pub -h <mqtt.server.host> -p 1883 -u "$MQTT_USER" -P "$MQTT_PASSWORD" -t /edge/point -m '{"test":1}'

Checklist:

  • mqtt.enable=true
  • mqtt.server.host/port/user/password is correct
  • The broker's ACL allows publishes from this client
  • Look for MQTT connected or reconnection logs in catalina.out

Sparkplug Topic Not Visible​

CheckHow to Verify
Is it sparkplug.enable=true?Check properties + restart required
Is the jar in lib?ls WebContent/WEB-INF/lib/tahu-core*.jar
Is it the same broker?mqtt.server.* must match the SPB settings
Broker's SPB topic ACLspBv1.0/# publish permission

NDEATH Appears to Be Published Twice​

This is normal behavior. Explicit publish on graceful shutdown + (since a will is also registered) the broker may also publish the will if it cannot detect the disconnection as a will-bypass. In that case, the host side should be implemented to process only one NDEATH with the same bdSeq.


Performance / Responsiveness​

OPC Start/Stop Takes 5 Seconds​

This is due to the intentional Thread.sleep in ConnectService (to guarantee collector warm-up).

  • Temporary workaround: Refresh the screen to check the polling response
  • Permanent fix: Apply the subsequent PR in REFACTORING_PLAN.md Phase A1 (Thread.sleep removal / CountDownLatch)

Slow Initial Screen Load​

There may be an additional 1–2 second delay due to opcList() N+1 queries + LastValueMap lookup distribution.

  • Improvement is planned with Phase B1 (IN batch select) and B2 (single facade)

Modifying One OPC Temporarily Interrupts Others​

This is because OPCUAServerManager.restart() is a full restart (Phase A2 — partial reload target).

Emergency workaround: Perform OPC modifications outside of operating hours.


Data / Cassandra​

Tombstone Accumulation Warning​

When deleting multiple OPCs during operation, the nodetool cfstats pe.app_tag tombstone metrics may temporarily spike.

  • Not critical, as this gateway typically manages ≤ 1000 OPCs/Tags
  • Time series (TM_TAG_POINT) is the responsibility of plantpulse-timeseries-engine, not this gateway

tag not found: <id>​

Frequently occurs during PUT /api/v1/tag/{tagId} or reads.

Causes:

  • tag_id typo
  • APP_TAG.xml is a R03 query in ALLOW FILTERING, so the partition key is not specified. The tag_id must be accurate.

To verify:

cqlsh -u cassandra -p cassandra -k pe -e "SELECT tag_id FROM app_tag;"

tag write not supported for opc_type=... When Writing a Value​

Write is not currently supported for protocols other than HTTP.

  • Only HTTPDriver.bind() is implemented
  • Write support for other protocols requires SPI extension, along with Sparkplug Phase 3 (NCMD/DCMD)

Security / Operations​

/api/* Exposed Without Authentication​

This is by design for on-premises networks (/api/* not included in SecurityFilter check-pattern). When exposing externally, place mTLS / API Key / Basic auth on the front of the reverse proxy.

CSRF​

CSRF applies only to the *_.do pattern. v1 mutation endpoints are excluded. Review together when exposing externally.


Log Collection Guide​

Attach the following when reporting an issue to speed up analysis.

# 환경
curl -s http://localhost:8080/api/v1/edge

# OPC 상태
curl -s http://localhost:8080/api/v1/opc

# 시스템 메트릭
curl -s http://localhost:8080/api/v1/monitoring

# 최근 로그
tail -n 500 $CATALINA_HOME/logs/catalina.out

Mask passwords in app.properties before attaching.