Skip to content

fix: MQTT settings silently fail to persist when broker is unreachable#9934

Merged
thebentern merged 6 commits into
meshtastic:developfrom
rcatal01:fix/mqtt-config-persistence
Mar 19, 2026
Merged

fix: MQTT settings silently fail to persist when broker is unreachable#9934
thebentern merged 6 commits into
meshtastic:developfrom
rcatal01:fix/mqtt-config-persistence

Conversation

@rcatal01

Copy link
Copy Markdown
Contributor

Summary

  • isValidConfig() was testing broker connectivity via connectPubSub() during config validation
  • When the broker was unreachable (network not ready, DNS failure, server down), the function returned false, causing AdminModule::handleSetModuleConfig() to skip saving settings entirely — silently
  • This removes the connectivity test from isValidConfig(), which now only validates configuration correctness (TLS support check, default server port check)
  • Connectivity is handled by the MQTT module's existing reconnect loop after settings are saved

Fixes #9107

Root Cause

In MQTT::isValidConfig() (MQTT.cpp line 668-670), connectPubSub() was called to test broker connectivity as part of validation. When this failed, isValidConfig() returned false, which caused AdminModule (line 924-926) to return false before reaching line 930 where moduleConfig.mqtt = c.payload_variant.mqtt actually persists the settings.

The result: settings appeared to save but silently reverted. No error was shown to the user.

Changes

  • src/mqtt/MQTT.cpp: Removed connectPubSub() call and associated MQTTClient/PubSubClient object creation from isValidConfig(). The function now only validates config correctness, not connectivity.
  • test/test_mqtt/MQTT.cpp: Updated 4 unit tests to reflect that isValidConfig() no longer tests connectivity. test_configWithConnectionFailure renamed to test_configWithUnreachableServerIsStillValid and now asserts true.

Test plan

  • Built firmware for Heltec Wireless Tracker (ESP32-S3)
  • Changed MQTT settings via Meshtastic iOS app with no WiFi configured (broker unreachable)
  • Device rebooted after save
  • Reconnected via BLE — settings persisted correctly
  • Verified this was the exact scenario that failed on stock 2.7.15 firmware
  • Unit tests updated and should pass (removed connectivity assertions from validation tests)

isValidConfig() was testing broker connectivity via connectPubSub() as
part of config validation. When the broker was unreachable (network not
ready, DNS failure, server down), the function returned false, causing
AdminModule to skip saving settings entirely — silently.

This removes the connectivity test from isValidConfig(), which now only
validates configuration correctness (TLS support, default server port).
Connectivity is handled by the MQTT module's existing reconnect loop.

Fixes meshtastic#9107
@CLAassistant

CLAassistant commented Mar 18, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@github-actions

Copy link
Copy Markdown
Contributor

@rcatal01, Welcome to Meshtastic!

Thanks for opening your first pull request. We really appreciate it.

We discuss work as a team in discord, please join us in the #firmware channel.
There's a big backlog of patches at the moment. If you have time,
please help us with some code review and testing of other PRs!

Welcome to the team 😄

@github-actions github-actions Bot added first-contribution bugfix Pull request that fixes bugs labels Mar 18, 2026
@Xaositek

Copy link
Copy Markdown
Contributor

This may have a positive impact on #9876

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a configuration persistence bug where MQTT settings were not saved if the broker was unreachable during validation, by making MQTT::isValidConfig() validate configuration correctness only (not connectivity). This aligns validation with the intended behavior that the MQTT module’s reconnect loop handles connectivity after settings are persisted.

Changes:

  • Removed broker connectivity attempts from MQTT::isValidConfig() so unreachable brokers no longer block saving MQTT settings.
  • Updated MQTT unit tests to reflect the new validation semantics (connectivity not tested) and renamed the relevant test to match behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/mqtt/MQTT.cpp Stops treating broker connectivity as a config validity requirement; keeps TLS support and default-server port validation.
test/test_mqtt/MQTT.cpp Updates/renames unit tests to assert config validity without requiring broker connectivity.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread src/mqtt/MQTT.cpp Outdated
Comment on lines +654 to +662
if (config.tls_enabled) {
#if MQTT_SUPPORTS_TLS
MQTTClientTLS *tlsClient = new MQTTClientTLS;
clientConnection.reset(tlsClient);
tlsClient->setInsecure();
#else
#if !MQTT_SUPPORTS_TLS
LOG_ERROR("Invalid MQTT config: tls_enabled is not supported on this node");
return false;
#endif
} else {
clientConnection.reset(new MQTTClient);
}
std::unique_ptr<PubSubClient> pubSub(new PubSubClient);
if (isConnectedToNetwork()) {
return connectPubSub(parsed, *pubSub, (client != nullptr) ? *client : *clientConnection);
}
// Note: connectivity is intentionally NOT validated here.
// Settings must be saved even when the network is temporarily unavailable.
// The MQTT module's reconnect loop will establish the connection when possible.
@thebentern

thebentern commented Mar 18, 2026

Copy link
Copy Markdown
Contributor

@rcatal01 I think I'm in favor of this change because its currently confusing users, but I'm not sure silently failing a different way is better. I think perhaps we should throw a client notification up to the client letting them know that we could not reach the configured MQTT broker and to double check the settings.

Per maintainer feedback: instead of silently saving when the broker
can't be reached, send a WARNING notification to the client saying
"MQTT settings saved, but could not reach the MQTT server."

Settings still always persist regardless of connectivity — the core
fix from the previous commit is preserved. The notification is purely
advisory so users know to double-check their server address and
credentials if the connection test fails.

When the network is not available at all, the connectivity check is
skipped entirely with a log message.
@rcatal01

Copy link
Copy Markdown
Contributor Author

@thebentern Good point — silently succeeding isn't much better than silently failing. I've pushed an update that:

  • Still always saves settings (the core fix)
  • Attempts a connectivity check when the network is available
  • If the broker is unreachable, sends a WARNING client notification: "MQTT settings saved, but could not reach the MQTT server. Please verify the server address and credentials."
  • If the network isn't available at all (WiFi not connected yet), skips the check with a log message

This way users get clear feedback without losing their settings.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes MQTT configuration persistence when the broker is unreachable by changing how MQTT config validation behaves, so settings aren’t rejected (and therefore not saved) due to transient connectivity failures.

Changes:

  • Adjusts MQTT::isValidConfig() to avoid failing validation when an MQTT connection attempt fails, and emits a warning instead.
  • Updates MQTT unit tests to expect isValidConfig() to return true even when the broker is unreachable.
  • Renames/updates related test cases and comments to reflect the new validation behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
src/mqtt/MQTT.cpp Changes MQTT config validation to no longer fail on unreachable broker; adds warning/notification path.
test/test_mqtt/MQTT.cpp Updates unit tests and naming to align with new isValidConfig() behavior.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread src/mqtt/MQTT.cpp Outdated
Comment on lines +673 to +675
std::unique_ptr<PubSubClient> pubSub(new PubSubClient);
if (!connectPubSub(parsed, *pubSub, (client != nullptr) ? *client : *clientConnection)) {
const char *warning = "MQTT settings saved, but could not reach the MQTT server. Please verify the server address and credentials.";
Comment thread src/mqtt/MQTT.cpp Outdated
}
std::unique_ptr<PubSubClient> pubSub(new PubSubClient);
if (!connectPubSub(parsed, *pubSub, (client != nullptr) ? *client : *clientConnection)) {
const char *warning = "MQTT settings saved, but could not reach the MQTT server. Please verify the server address and credentials.";
Comment thread src/mqtt/MQTT.cpp Outdated
Comment on lines +678 to +682
meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed();
cn->level = meshtastic_LogRecord_Level_WARNING;
cn->time = getValidTime(RTCQualityFromNet);
strncpy(cn->message, warning, sizeof(cn->message) - 1);
cn->message[sizeof(cn->message) - 1] = '\0';
Comment thread test/test_mqtt/MQTT.cpp Outdated
}

// Empty 'enabled' configuration is valid.
// Empty 'enabled' configuration is valid. Connectivity is verified but does not block saving.
Comment thread test/test_mqtt/MQTT.cpp Outdated
Comment on lines 849 to 850
// isValidConfig verifies connectivity but always returns true (settings always save).
void test_configCustomHostAndPort(void)
Comment thread test/test_mqtt/MQTT.cpp Outdated
- Fix warning message wording: "Settings will be saved" instead of
  "Settings saved" (notification fires before AdminModule persists)
- Add null check on clientNotificationPool.allocZeroed() to prevent
  crash if pool is exhausted (matches AdminModule::sendWarning pattern)
- Fix test comments to accurately describe conditional connectivity
  check behavior and IS_RUNNING_TESTS compile-out
@rcatal01

Copy link
Copy Markdown
Contributor Author

Pushed a follow-up commit addressing the Copilot review feedback:

  • Fixed warning message wording to reflect correct timing ("Settings will be saved" instead of "Settings saved")
  • Added null check on clientNotificationPool.allocZeroed() to match the AdminModule::sendWarning() pattern
  • Cleaned up test comments to accurately describe conditional behavior

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes MQTT settings not persisting when the broker/network is unreachable by ensuring MQTT::isValidConfig() no longer fails validation solely due to connection failures, allowing AdminModule to persist the new configuration and letting the MQTT reconnect loop handle connectivity later.

Changes:

  • Adjusted MQTT::isValidConfig() to not reject configs when broker connectivity checks fail (adds warning/log/notification instead).
  • Updated MQTT unit tests to reflect the new “unreachable broker is still valid” behavior and renamed the affected test.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/mqtt/MQTT.cpp Changes config validation behavior so unreachable broker doesn’t prevent saving; adds a warning path.
test/test_mqtt/MQTT.cpp Updates/renames unit tests to match the revised validation behavior.
Comments suppressed due to low confidence (1)

test/test_mqtt/MQTT.cpp:831

  • These unit tests still assert that isValidConfig() establishes a connection (client.connected_), which bakes connectivity side effects into config validation and will make future refactors (e.g., truly removing connectivity checks from isValidConfig) harder. Since the new intended behavior is “settings always save”, consider narrowing these tests to assert parsing/normalization (host/port) and return value, and reserve connection assertions for reconnect-loop tests.
// Empty 'enabled' configuration is valid. Connectivity is checked when network is available but does not block saving.
void test_configEnabledEmptyIsValid(void)
{
    meshtastic_ModuleConfig_MQTTConfig config = {.enabled = true};
    MockPubSubServer client;

    TEST_ASSERT_TRUE(MQTTUnitTest::isValidConfig(config, &client));
    TEST_ASSERT_TRUE(client.connected_);
    TEST_ASSERT_EQUAL_STRING(default_mqtt_address, client.host_.c_str());
    TEST_ASSERT_EQUAL(1883, client.port_);
}

You can also share your feedback on Copilot code review. Take the survey.

Comment thread src/mqtt/MQTT.cpp Outdated
Comment on lines 660 to 662
// Attempt to verify broker connectivity, but do NOT block saving settings if unreachable.
// The MQTT module's reconnect loop will establish the connection when possible.
if (isConnectedToNetwork()) {
Comment thread src/mqtt/MQTT.cpp Outdated
Comment on lines +662 to +675
if (isConnectedToNetwork()) {
return connectPubSub(parsed, *pubSub, (client != nullptr) ? *client : *clientConnection);
std::unique_ptr<MQTTClient> clientConnection;
if (config.tls_enabled) {
#if MQTT_SUPPORTS_TLS
MQTTClientTLS *tlsClient = new MQTTClientTLS;
clientConnection.reset(tlsClient);
tlsClient->setInsecure();
#endif
} else {
clientConnection.reset(new MQTTClient);
}
std::unique_ptr<PubSubClient> pubSub(new PubSubClient);
if (!connectPubSub(parsed, *pubSub, (client != nullptr) ? *client : *clientConnection)) {
const char *warning = "Could not reach the MQTT server. Settings will be saved, but please verify the server address and credentials.";
Comment thread src/mqtt/MQTT.cpp Outdated
Comment on lines +663 to +674
std::unique_ptr<MQTTClient> clientConnection;
if (config.tls_enabled) {
#if MQTT_SUPPORTS_TLS
MQTTClientTLS *tlsClient = new MQTTClientTLS;
clientConnection.reset(tlsClient);
tlsClient->setInsecure();
#endif
} else {
clientConnection.reset(new MQTTClient);
}
std::unique_ptr<PubSubClient> pubSub(new PubSubClient);
if (!connectPubSub(parsed, *pubSub, (client != nullptr) ? *client : *clientConnection)) {
Reverts the advisory connectivity check added in the previous commit.
While the intent was to warn users about unreachable brokers,
connectPubSub() mutates the isConnected state of the running MQTT
module and performs synchronous network operations that can block
the config-save path.

The cleanest approach: isValidConfig() validates config correctness
only (TLS support, default server port). The MQTT reconnect loop
handles connectivity after settings are persisted and the device
reboots. If the broker is unreachable, the user will see it in the
MQTT connection status — no special notification needed.

This returns to the simpler design from the first commit, which was
tested on hardware and confirmed working.
@rcatal01

Copy link
Copy Markdown
Contributor Author

After reviewing the Copilot feedback on the advisory connectivity check, I've removed it entirely and returned to the simpler approach from the first commit.

The issue: connectPubSub() mutates the file-scope isConnected flag, which can temporarily put the running MQTT module into a disconnected state during what should be a config validation. It also performs synchronous network operations that can block the config-save path on DNS/TCP timeouts.

The cleaner solution: isValidConfig() now only validates configuration correctness (TLS support check, default server port check). The MQTT reconnect loop handles connectivity after settings are persisted and the device reboots. If the broker is unreachable, the user will see it in the MQTT connection status — no special validation-time notification needed.

This is the version that was tested on hardware (Heltec Wireless Tracker) and confirmed working: MQTT settings now persist regardless of broker reachability.

@thebentern

Copy link
Copy Markdown
Contributor

@rcatal01 I'm not in favor of this as-is. Removing the connectivity check diagnostic with client notification strips that whole process of any value it had before and people will end up being confused the other direction when their mqtt connection doesn't work, with no feedback.

@Xaositek Xaositek left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing my approval at this time - this PR has changed quite a bit

Per maintainer feedback: users need connectivity feedback, but
connectPubSub() mutates the module's isConnected state.

This uses a standalone MQTTClient TCP connection test that:
- Checks if the server IP/port is reachable
- Sends a WARNING notification if unreachable
- Does NOT establish an MQTT session or mutate any module state
- Does NOT block saving — isValidConfig always returns true

The TCP test client is created locally, used, and destroyed within
the function scope. No side effects on the running MQTT module.
@rcatal01

Copy link
Copy Markdown
Contributor Author

@thebentern @Xaositek Understood — I agree users need connectivity feedback. The issue Copilot raised is that connectPubSub() mutates the module's isConnected state as a side effect.

Would a lightweight TCP-only connection test be acceptable? The idea: use a standalone MQTTClient scoped locally within isValidConfig() to check if the server IP/port is reachable, send a WARNING notification if not, then destroy the test client. No MQTT session, no state mutation, settings still always save.

Want to confirm this direction before I push more code.

@ackstorm23

ackstorm23 commented Mar 18, 2026

Copy link
Copy Markdown

@rcatal01 I think I'm in favor of this change because its currently confusing users, but I'm not sure silently failing a different way is better. I think perhaps we should throw a client notification up to the client letting them know that we could not reach the configured MQTT broker and to double check the settings.

I still believe there are bugs in the code because it will claim to not be able to reach a server that it was connecting to without issue just fine for days until I disable MQTT, and when re-enabling it with the same settings it will log that the server is unreachable and refuse to enable it. Network captures at the time showed no attempt to connect so I think it's logging does not provide enough information about the failure to determine what is actually failing.

The original pubsub codebase has not been updated since 2020, and was absolutely full of unresolved git issues. They are using a fork maintained by one man which received some updates but has not been updated in a year. It may simply be that the pubsub codebase is buggy and we are victim to using that implementation. 🤷

Looks like hmueller01 is the only person actively maintaining a fork at this point, with many updates.

@ackstorm23

ackstorm23 commented Mar 18, 2026

Copy link
Copy Markdown

@rcatal01 I'm not in favor of this as-is. Removing the connectivity check diagnostic with client notification strips that whole process of any value it had before and people will end up being confused the other direction when their mqtt connection doesn't work, with no feedback.

to be fair, the 'feedback' it provides now is not helpful. It provides no details about the failure, simply stating that it could not connect.

Was it a failure because of temporarily DNS resolution? Was it actually unable to reach the target? did it take too long to get a response from the target? did it actually try to connect at all? (I've seen packet captures where it did not even try to connect over the fire) or maybe it received an unexpected reply from the MQTT server. No clues are given.

We don't even know if it would self-recover after the first failure because it never gives the opportunity to try.

On another note, anyone who might want to pre-configure MQTT ahead of time for a device so that it's already ready to transmit when deployed is actively blocked from doing so because the MQTT server simply has to be reachable at the time it is turned on. 🤷

IMHO it should turn MQTT on or off, and not care if it can connect or not. It will already log each time it cannot reach the MQTT server so it's not as if the user has no way to know if there is a problem.

@thebentern thebentern requested a review from Copilot March 19, 2026 13:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes an MQTT configuration persistence bug where AdminModule would refuse to save settings if MQTT::isValidConfig() failed due to broker/network reachability, causing silent reversion when the broker was unreachable.

Changes:

  • Removed the blocking “must-connect” behavior from MQTT::isValidConfig() so config validity is no longer tied to broker reachability.
  • Added a non-blocking, best-effort TCP reachability warning (without mutating MQTT module connection state).
  • Updated MQTT unit tests to reflect that unreachable brokers no longer invalidate configuration.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/mqtt/MQTT.cpp Stops treating broker connectivity as a validation failure; adds a warning-only reachability check.
test/test_mqtt/MQTT.cpp Updates unit tests to assert configs remain valid even when the broker is unreachable.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread src/mqtt/MQTT.cpp
Comment on lines 648 to +666
bool MQTT::isValidConfig(const meshtastic_ModuleConfig_MQTTConfig &config, MQTTClient *client)
{
const PubSubConfig parsed(config);

if (config.enabled && !config.proxy_to_client_enabled) {
#if HAS_NETWORKING
std::unique_ptr<MQTTClient> clientConnection;
if (config.tls_enabled) {
#if MQTT_SUPPORTS_TLS
MQTTClientTLS *tlsClient = new MQTTClientTLS;
clientConnection.reset(tlsClient);
tlsClient->setInsecure();
#else
#if !MQTT_SUPPORTS_TLS
LOG_ERROR("Invalid MQTT config: tls_enabled is not supported on this node");
return false;
#endif
} else {
clientConnection.reset(new MQTTClient);
}
std::unique_ptr<PubSubClient> pubSub(new PubSubClient);
// Perform a lightweight TCP connectivity check without using connectPubSub(),
// which mutates the module's isConnected state. This only checks if the server
// is reachable — it does not establish an MQTT session.
// Settings are always saved regardless of the result.
if (isConnectedToNetwork()) {
return connectPubSub(parsed, *pubSub, (client != nullptr) ? *client : *clientConnection);
MQTTClient testClient;
if (!testClient.connect(parsed.serverAddr.c_str(), parsed.serverPort)) {
Comment thread src/mqtt/MQTT.cpp
@thebentern thebentern merged commit 0ea408e into meshtastic:develop Mar 19, 2026
81 checks passed
thebentern added a commit that referenced this pull request Mar 22, 2026
#9934)

* fix: MQTT settings silently fail to persist when broker is unreachable

isValidConfig() was testing broker connectivity via connectPubSub() as
part of config validation. When the broker was unreachable (network not
ready, DNS failure, server down), the function returned false, causing
AdminModule to skip saving settings entirely — silently.

This removes the connectivity test from isValidConfig(), which now only
validates configuration correctness (TLS support, default server port).
Connectivity is handled by the MQTT module's existing reconnect loop.

Fixes #9107

* Add client warning notification when MQTT broker is unreachable

Per maintainer feedback: instead of silently saving when the broker
can't be reached, send a WARNING notification to the client saying
"MQTT settings saved, but could not reach the MQTT server."

Settings still always persist regardless of connectivity — the core
fix from the previous commit is preserved. The notification is purely
advisory so users know to double-check their server address and
credentials if the connection test fails.

When the network is not available at all, the connectivity check is
skipped entirely with a log message.

* Address Copilot review feedback

- Fix warning message wording: "Settings will be saved" instead of
  "Settings saved" (notification fires before AdminModule persists)
- Add null check on clientNotificationPool.allocZeroed() to prevent
  crash if pool is exhausted (matches AdminModule::sendWarning pattern)
- Fix test comments to accurately describe conditional connectivity
  check behavior and IS_RUNNING_TESTS compile-out

* Remove connectivity check from isValidConfig entirely

Reverts the advisory connectivity check added in the previous commit.
While the intent was to warn users about unreachable brokers,
connectPubSub() mutates the isConnected state of the running MQTT
module and performs synchronous network operations that can block
the config-save path.

The cleanest approach: isValidConfig() validates config correctness
only (TLS support, default server port). The MQTT reconnect loop
handles connectivity after settings are persisted and the device
reboots. If the broker is unreachable, the user will see it in the
MQTT connection status — no special notification needed.

This returns to the simpler design from the first commit, which was
tested on hardware and confirmed working.

* Use lightweight TCP check instead of connectPubSub for validation

Per maintainer feedback: users need connectivity feedback, but
connectPubSub() mutates the module's isConnected state.

This uses a standalone MQTTClient TCP connection test that:
- Checks if the server IP/port is reachable
- Sends a WARNING notification if unreachable
- Does NOT establish an MQTT session or mutate any module state
- Does NOT block saving — isValidConfig always returns true

The TCP test client is created locally, used, and destroyed within
the function scope. No side effects on the running MQTT module.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
jeek pushed a commit to jeek/Meshtastic-Exploiteers-Hacker-Pager that referenced this pull request Jun 30, 2026
meshtastic#9934)

* fix: MQTT settings silently fail to persist when broker is unreachable

isValidConfig() was testing broker connectivity via connectPubSub() as
part of config validation. When the broker was unreachable (network not
ready, DNS failure, server down), the function returned false, causing
AdminModule to skip saving settings entirely — silently.

This removes the connectivity test from isValidConfig(), which now only
validates configuration correctness (TLS support, default server port).
Connectivity is handled by the MQTT module's existing reconnect loop.

Fixes meshtastic#9107

* Add client warning notification when MQTT broker is unreachable

Per maintainer feedback: instead of silently saving when the broker
can't be reached, send a WARNING notification to the client saying
"MQTT settings saved, but could not reach the MQTT server."

Settings still always persist regardless of connectivity — the core
fix from the previous commit is preserved. The notification is purely
advisory so users know to double-check their server address and
credentials if the connection test fails.

When the network is not available at all, the connectivity check is
skipped entirely with a log message.

* Address Copilot review feedback

- Fix warning message wording: "Settings will be saved" instead of
  "Settings saved" (notification fires before AdminModule persists)
- Add null check on clientNotificationPool.allocZeroed() to prevent
  crash if pool is exhausted (matches AdminModule::sendWarning pattern)
- Fix test comments to accurately describe conditional connectivity
  check behavior and IS_RUNNING_TESTS compile-out

* Remove connectivity check from isValidConfig entirely

Reverts the advisory connectivity check added in the previous commit.
While the intent was to warn users about unreachable brokers,
connectPubSub() mutates the isConnected state of the running MQTT
module and performs synchronous network operations that can block
the config-save path.

The cleanest approach: isValidConfig() validates config correctness
only (TLS support, default server port). The MQTT reconnect loop
handles connectivity after settings are persisted and the device
reboots. If the broker is unreachable, the user will see it in the
MQTT connection status — no special notification needed.

This returns to the simpler design from the first commit, which was
tested on hardware and confirmed working.

* Use lightweight TCP check instead of connectPubSub for validation

Per maintainer feedback: users need connectivity feedback, but
connectPubSub() mutates the module's isConnected state.

This uses a standalone MQTTClient TCP connection test that:
- Checks if the server IP/port is reachable
- Sends a WARNING notification if unreachable
- Does NOT establish an MQTT session or mutate any module state
- Does NOT block saving — isValidConfig always returns true

The TCP test client is created locally, used, and destroyed within
the function scope. No side effects on the running MQTT module.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Pull request that fixes bugs first-contribution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: MQTT cannot be configured

6 participants