This is an automated email from the ASF dual-hosted git repository.

jason810496 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new fcac4a1941a Fix OpenSearch remote logging crash if port is empty 
(#71170)
fcac4a1941a is described below

commit fcac4a1941a7569109d5ef536a9b351738f33d6e
Author: PoAn Yang <[email protected]>
AuthorDate: Tue Aug 25 01:01:43 2026 +0900

    Fix OpenSearch remote logging crash if port is empty (#71170)
    
    Signed-off-by: PoAn Yang <[email protected]>
---
 .../config_templates/airflow_local_settings.py     |  5 +++-
 .../test_airflow_local_settings.py                 | 28 ++++++++++++++++++++++
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git 
a/airflow-core/src/airflow/config_templates/airflow_local_settings.py 
b/airflow-core/src/airflow/config_templates/airflow_local_settings.py
index c5bb91b682f..f138a6c7667 100644
--- a/airflow-core/src/airflow/config_templates/airflow_local_settings.py
+++ b/airflow-core/src/airflow/config_templates/airflow_local_settings.py
@@ -357,7 +357,10 @@ if REMOTE_LOGGING:
     elif OPENSEARCH_HOST:
         from airflow.providers.opensearch.log.os_task_handler import 
OpensearchRemoteLogIO
 
-        OPENSEARCH_PORT = conf.getint("opensearch", "PORT", fallback=9200)
+        # ``[opensearch] port`` declares an empty-string default, so the key 
is always present and
+        # ``conf.getint`` raises on ``int("")`` instead of falling back to 
9200.
+        _opensearch_port = conf.get("opensearch", "PORT", fallback="")
+        OPENSEARCH_PORT = int(_opensearch_port) if _opensearch_port else 9200
         OPENSEARCH_USERNAME: str = conf.get_mandatory_value("opensearch", 
"USERNAME")
         OPENSEARCH_PASSWORD: str = conf.get_mandatory_value("opensearch", 
"PASSWORD")
         OPENSEARCH_WRITE_STDOUT: bool = conf.getboolean("opensearch", 
"WRITE_STDOUT")
diff --git 
a/airflow-core/tests/unit/config_templates/test_airflow_local_settings.py 
b/airflow-core/tests/unit/config_templates/test_airflow_local_settings.py
index 088bc4bcca9..8bc91d11c4f 100644
--- a/airflow-core/tests/unit/config_templates/test_airflow_local_settings.py
+++ b/airflow-core/tests/unit/config_templates/test_airflow_local_settings.py
@@ -131,6 +131,34 @@ def test_mixed_kwargs_split_correctly(remote_base, 
remote_io_path, restore_local
         assert "backup_count" not in mock_remote_io.call_args.kwargs
 
 
[email protected](
+    ("configured_port", "expected_port"),
+    [
+        pytest.param("", 9200, id="unset-falls-back-to-9200"),
+        pytest.param("9201", 9201, id="explicit-port-is-an-int"),
+    ],
+)
+def test_opensearch_port_resolution(configured_port, expected_port, 
restore_local_settings):
+    """``[opensearch] port`` defaults to an empty string, which must not blow 
up module import."""
+    remote_io_path = 
"airflow.providers.opensearch.log.os_task_handler.OpensearchRemoteLogIO"
+    pytest.importorskip(remote_io_path.rsplit(".", 1)[0])
+    with (
+        mock.patch(remote_io_path) as mock_remote_io,
+        conf_vars(
+            {
+                ("logging", "remote_logging"): "True",
+                ("logging", "remote_base_log_folder"): "",
+                ("elasticsearch", "host"): "",
+                ("opensearch", "host"): "https://opensearch.example.com:9202";,
+                ("opensearch", "port"): configured_port,
+            }
+        ),
+    ):
+        importlib.reload(airflow_local_settings)
+
+        assert mock_remote_io.call_args.kwargs["port"] == expected_port
+
+
 def test_file_handler_params_introspected_correctly():
     """The introspected FileTaskHandler params include the expected kwargs."""
     init_params = set(inspect.signature(FileTaskHandler.__init__).parameters) 
- {"self", "base_log_folder"}

Reply via email to