diff --git a/news/174.bugfix b/news/174.bugfix
new file mode 100644
index 0000000..f581b33
--- /dev/null
+++ b/news/174.bugfix
@@ -0,0 +1,1 @@
+Fix AttributeError when accessing config in struct-mode with get() while providing None as default
diff --git a/omegaconf/basecontainer.py b/omegaconf/basecontainer.py
index 83b41ef..db52399 100644
--- a/omegaconf/basecontainer.py
+++ b/omegaconf/basecontainer.py
@@ -19,6 +19,8 @@ from ._utils import (
 from .base import Container, ContainerMetadata, Node
 from .errors import MissingMandatoryValue, ReadonlyConfigError, ValidationError
 
+DEFAULT_VALUE_MARKER: Any = object()
+
 
 class BaseContainer(Container, ABC):
     # static
@@ -42,7 +44,10 @@ class BaseContainer(Container, ABC):
         OmegaConf.save(self, f)
 
     def _resolve_with_default(
-        self, key: Union[str, int, Enum], value: Any, default_value: Any = None
+        self,
+        key: Union[str, int, Enum],
+        value: Any,
+        default_value: Any = DEFAULT_VALUE_MARKER,
     ) -> Any:
         """returns the value with the specified key, like obj.key and obj['key']"""
 
@@ -51,7 +56,9 @@ class BaseContainer(Container, ABC):
 
         value = _get_value(value)
 
-        if default_value is not None and (value is None or is_mandatory_missing(value)):
+        if default_value is not DEFAULT_VALUE_MARKER and (
+            value is None or is_mandatory_missing(value)
+        ):
             value = default_value
 
         value = self._resolve_str_interpolation(
diff --git a/omegaconf/dictconfig.py b/omegaconf/dictconfig.py
index 2d64bc9..0143758 100644
--- a/omegaconf/dictconfig.py
+++ b/omegaconf/dictconfig.py
@@ -24,7 +24,7 @@ from ._utils import (
     is_structured_config_frozen,
 )
 from .base import Container, ContainerMetadata, Node
-from .basecontainer import BaseContainer
+from .basecontainer import DEFAULT_VALUE_MARKER, BaseContainer
 from .errors import (
     KeyValidationError,
     MissingMandatoryValue,
@@ -247,7 +247,7 @@ class DictConfig(BaseContainer, MutableMapping[str, Any]):
         if key == "__members__":
             raise AttributeError()
 
-        return self.get(key=key, default_value=None)
+        return self.get(key=key)
 
     def __getitem__(self, key: Union[str, Enum]) -> Any:
         """
@@ -256,11 +256,13 @@ class DictConfig(BaseContainer, MutableMapping[str, Any]):
         :return:
         """
         try:
-            return self.get(key=key, default_value=None)
+            return self.get(key=key)
         except AttributeError as e:
             raise KeyError(str(e))
 
-    def get(self, key: Union[str, Enum], default_value: Any = None) -> Any:
+    def get(
+        self, key: Union[str, Enum], default_value: Any = DEFAULT_VALUE_MARKER,
+    ) -> Any:
         key = self._validate_and_normalize_key(key)
         node = self.get_node_ex(key=key, default_value=default_value)
         return self._resolve_with_default(
@@ -268,12 +270,12 @@ class DictConfig(BaseContainer, MutableMapping[str, Any]):
         )
 
     def get_node(self, key: Union[str, Enum]) -> Node:
-        return self.get_node_ex(key)
+        return self.get_node_ex(key, default_value=DEFAULT_VALUE_MARKER)
 
     def get_node_ex(
         self,
         key: Union[str, Enum],
-        default_value: Any = None,
+        default_value: Any = DEFAULT_VALUE_MARKER,
         validate_access: bool = True,
     ) -> Node:
         value: Node = self.__dict__["_content"].get(key)
@@ -281,18 +283,18 @@ class DictConfig(BaseContainer, MutableMapping[str, Any]):
             try:
                 self._validate_get(key)
             except (KeyError, AttributeError):
-                if default_value is not None:
+                if default_value != DEFAULT_VALUE_MARKER:
                     value = default_value
                 else:
                     raise
         else:
-            if default_value is not None:
+            if default_value is not DEFAULT_VALUE_MARKER:
                 value = default_value
         return value
 
-    __marker = object()
+    __pop_marker = object()
 
-    def pop(self, key: Union[str, Enum], default: Any = __marker) -> Any:
+    def pop(self, key: Union[str, Enum], default: Any = __pop_marker) -> Any:
         key = self._validate_and_normalize_key(key)
         if self._get_flag("readonly"):
             raise ReadonlyConfigError(self._get_full_key(key))
@@ -301,7 +303,7 @@ class DictConfig(BaseContainer, MutableMapping[str, Any]):
             value=self.__dict__["_content"].pop(key, default),
             default_value=default,
         )
-        if value is self.__marker:
+        if value is self.__pop_marker:
             raise KeyError(key)
         return value
 
@@ -328,7 +330,7 @@ class DictConfig(BaseContainer, MutableMapping[str, Any]):
             return False
         else:
             try:
-                self._resolve_with_default(key, node, None)
+                self._resolve_with_default(key=key, value=node)
                 return True
             except UnsupportedInterpolationType:
                 # Value that has unsupported interpolation counts as existing.

diff --git a/tests/test_basic_ops_dict.py b/tests/test_basic_ops_dict.py
index f8c7220..aa46b86 100644
--- a/tests/test_basic_ops_dict.py
+++ b/tests/test_basic_ops_dict.py
@@ -52,7 +52,7 @@ def test_getattr_dict() -> None:
 
 
 def test_mandatory_value() -> None:
-    c = OmegaConf.create(dict(a="???"))
+    c = OmegaConf.create({"a": "???"})
     with pytest.raises(MissingMandatoryValue, match="a"):
         c.a
 
@@ -270,8 +270,7 @@ def test_dict_pop(
 )
 def test_in_dict(conf: Any, key: str, expected: Any) -> None:
     conf = OmegaConf.create(conf)
-    ret = key in conf
-    assert ret == expected
+    assert (key in conf) == expected
 
 
 def test_get_root() -> None:
@@ -387,10 +386,11 @@ def test_hash() -> None:
     assert hash(c1) != hash(c2)
 
 
-def test_get_with_default_from_struct_not_throwing() -> None:
-    c = OmegaConf.create(dict(a=10, b=20))
+@pytest.mark.parametrize("default", ["default", 0, None])  # type: ignore
+def test_get_with_default_from_struct_not_throwing(default: Any) -> None:
+    c = OmegaConf.create({"a": 10, "b": 20})
     OmegaConf.set_struct(c, True)
-    assert c.get("z", "default") == "default"
+    assert c.get("z", default) == default
 
 
 def test_members() -> None:
diff --git a/tests/test_struct.py b/tests/test_struct.py
index f8ec370..c6016d8 100644
--- a/tests/test_struct.py
+++ b/tests/test_struct.py
@@ -13,7 +13,7 @@ def test_struct_default() -> None:
 
 
 def test_struct_set_on_dict() -> None:
-    c = OmegaConf.create(dict(a=dict()))
+    c = OmegaConf.create({"a": {}})
     OmegaConf.set_struct(c, True)
     # Throwing when it hits foo, so exception key is a.foo and not a.foo.bar
     with pytest.raises(AttributeError, match=re.escape("a.foo")):

[bug] .get on ConfigNode with default None throws keyerror in struct mode
Minimal example:
```python
cfg = omegaconf.OmegaConf.create()
omegaconf.OmegaConf.set_struct(cfg, True)
a.get("d", None)
...
AttributeError: Accessing unknown key in a struct : d
```
Version: `2.0.0rc15`
tests/test_basic_ops_dict.py::test_get_with_default_from_struct_not_throwing[None]
tests/test_basic_ops_dict.py::test_setattr_deep_value tests/test_basic_ops_dict.py::test_setattr_deep_from_empty tests/test_basic_ops_dict.py::test_setattr_deep_map tests/test_basic_ops_dict.py::test_getattr tests/test_basic_ops_dict.py::test_getattr_dict tests/test_basic_ops_dict.py::test_mandatory_value tests/test_basic_ops_dict.py::test_nested_dict_mandatory_value tests/test_basic_ops_dict.py::test_mandatory_with_default tests/test_basic_ops_dict.py::test_subscript_get tests/test_basic_ops_dict.py::test_subscript_set tests/test_basic_ops_dict.py::test_pretty_dict tests/test_basic_ops_dict.py::test_pretty_sort_keys tests/test_basic_ops_dict.py::test_pretty_dict_unicode tests/test_basic_ops_dict.py::test_default_value tests/test_basic_ops_dict.py::test_get_default_value tests/test_basic_ops_dict.py::test_scientific_notation_float tests/test_basic_ops_dict.py::test_dict_get_with_default tests/test_basic_ops_dict.py::test_map_expansion tests/test_basic_ops_dict.py::test_items tests/test_basic_ops_dict.py::test_items2 tests/test_basic_ops_dict.py::test_items_with_interpolation tests/test_basic_ops_dict.py::test_dict_keys tests/test_basic_ops_dict.py::test_pickle_get_root tests/test_basic_ops_dict.py::test_iterate_dictionary tests/test_basic_ops_dict.py::test_dict_pop[cfg0-a-None-1-expectation0] tests/test_basic_ops_dict.py::test_dict_pop[cfg1-not_found-default-default-expectation1] tests/test_basic_ops_dict.py::test_dict_pop[cfg2-not_found-None-None-expectation2] tests/test_basic_ops_dict.py::test_dict_pop[cfg3-a-None-2-expectation3] tests/test_basic_ops_dict.py::test_dict_pop[cfg4-a-None-None-expectation4] tests/test_basic_ops_dict.py::test_dict_pop[cfg5-a-None-None-expectation5] tests/test_basic_ops_dict.py::test_dict_pop[cfg6-Enum1.FOO-None-bar-expectation6] tests/test_basic_ops_dict.py::test_dict_pop[cfg7-Enum1.BAR-default-default-expectation7] tests/test_basic_ops_dict.py::test_dict_pop[cfg8-Enum1.BAR-None-None-expectation8] tests/test_basic_ops_dict.py::test_in_dict[conf0-a-True] tests/test_basic_ops_dict.py::test_in_dict[conf1-b-True] tests/test_basic_ops_dict.py::test_in_dict[conf2-c-False] tests/test_basic_ops_dict.py::test_in_dict[conf3-b-True] tests/test_basic_ops_dict.py::test_in_dict[conf4-b-False] tests/test_basic_ops_dict.py::test_in_dict[conf5-c-False] tests/test_basic_ops_dict.py::test_in_dict[conf6-b-False] tests/test_basic_ops_dict.py::test_in_dict[conf7-a-True] tests/test_basic_ops_dict.py::test_in_dict[conf8-b-True] tests/test_basic_ops_dict.py::test_in_dict[conf9-b-True] tests/test_basic_ops_dict.py::test_in_dict[conf10-Enum1.FOO-True] tests/test_basic_ops_dict.py::test_get_root tests/test_basic_ops_dict.py::test_get_root_of_merged tests/test_basic_ops_dict.py::test_dict_config tests/test_basic_ops_dict.py::test_dict_delitem tests/test_basic_ops_dict.py::test_dict_len[d0-0] tests/test_basic_ops_dict.py::test_dict_len[d1-2] tests/test_basic_ops_dict.py::test_dict_assign_illegal_value tests/test_basic_ops_dict.py::test_dict_assign_illegal_value_nested tests/test_basic_ops_dict.py::test_assign_dict_in_dict tests/test_basic_ops_dict.py::test_to_container[src0] tests/test_basic_ops_dict.py::test_to_container[src1] tests/test_basic_ops_dict.py::test_to_container[src2] tests/test_basic_ops_dict.py::test_pretty_without_resolve tests/test_basic_ops_dict.py::test_pretty_with_resolve tests/test_basic_ops_dict.py::test_instantiate_config_fails tests/test_basic_ops_dict.py::test_dir tests/test_basic_ops_dict.py::test_hash tests/test_basic_ops_dict.py::test_get_with_default_from_struct_not_throwing[default] tests/test_basic_ops_dict.py::test_get_with_default_from_struct_not_throwing[0] tests/test_basic_ops_dict.py::test_members tests/test_basic_ops_dict.py::test_masked_copy[in_cfg0-mask_keys0-expected0] tests/test_basic_ops_dict.py::test_masked_copy[in_cfg1-a-expected1] tests/test_basic_ops_dict.py::test_masked_copy[in_cfg2-mask_keys2-expected2] tests/test_basic_ops_dict.py::test_masked_copy[in_cfg3-b-expected3] tests/test_basic_ops_dict.py::test_masked_copy[in_cfg4-mask_keys4-expected4] tests/test_basic_ops_dict.py::test_masked_copy_is_deep tests/test_basic_ops_dict.py::test_creation_with_invalid_key tests/test_basic_ops_dict.py::test_set_with_invalid_key tests/test_basic_ops_dict.py::test_get_with_invalid_key tests/test_basic_ops_dict.py::test_hasattr tests/test_basic_ops_dict.py::test_struct_mode_missing_key_getitem tests/test_basic_ops_dict.py::test_struct_mode_missing_key_setitem tests/test_basic_ops_dict.py::test_get_type tests/test_basic_ops_dict.py::test_is_missing tests/test_struct.py::test_struct_default tests/test_struct.py::test_struct_set_on_dict tests/test_struct.py::test_struct_set_on_nested_dict tests/test_struct.py::test_merge_dotlist_into_struct tests/test_struct.py::test_merge_config_with_struct[in_base0-in_merged0] tests/test_struct.py::test_struct_contain_missing