diff --git a/src/pymatlib/core/alloy.py b/src/pymatlib/core/alloy.py
index e612aec3225d4b59d5ccc83b798ef7c4a515ad82..190252a6dd182c2ca94a9f2f86088e7ef3b37200 100644
--- a/src/pymatlib/core/alloy.py
+++ b/src/pymatlib/core/alloy.py
@@ -115,6 +115,12 @@ class Alloy:
                 - If solidus temperature is greater than liquidus temperature.
                 - If temperatures are outside the general range for alloys (450 K to 2000 K).
         """
+        if not isinstance(self.temperature_solidus, float):
+            raise AlloyTemperatureError(f"Solidus temperature must be a float, "
+                                        f"got {type(self.temperature_solidus).__name__}.")
+        if not isinstance(self.temperature_liquidus, float):
+            raise AlloyTemperatureError(f"Liquidus temperature must be a float, "
+                                        f"got {type(self.temperature_liquidus).__name__}.")
         if self.temperature_solidus > self.temperature_liquidus:
             raise AlloyTemperatureError("The solidus temperature must be less than or equal to the liquidus temperature.")
         if not (450 <= self.temperature_solidus <= 1900):
diff --git a/src/pymatlib/core/data_handler.py b/src/pymatlib/core/data_handler.py
index 8b71b33d159d1d900e42081b63aec8439f76b6ec..dd2b189078de8dbb4f5ea2a4e589942e449a8302 100644
--- a/src/pymatlib/core/data_handler.py
+++ b/src/pymatlib/core/data_handler.py
@@ -239,7 +239,7 @@ def read_data_from_file(file_config: Union[str, Dict], header: bool = True) -> T
             temp = df[temp_col].to_numpy(dtype=np.float64)
         else:
             raise ValueError(f"Temperature column '{temp_col}' not found in file. "
-                             f"Available columns: {', '.join(df.columns)}")
+                             f"\n -> Available columns: {', '.join(df.columns)}")
     else:
         if temp_col >= len(df.columns):
             raise ValueError(f"Temperature column index {temp_col} out of bounds (file has {len(df.columns)} columns)")
@@ -250,7 +250,7 @@ def read_data_from_file(file_config: Union[str, Dict], header: bool = True) -> T
             prop = df[prop_col].to_numpy(dtype=np.float64)
         else:
             raise ValueError(f"Property column '{prop_col}' not found in file. "
-                             f"Available columns: {', '.join(df.columns)}")
+                             f"\n -> Available columns: {', '.join(df.columns)}")
     else:
         if prop_col >= len(df.columns):
             raise ValueError(f"Property column index {prop_col} out of bounds (file has {len(df.columns)} columns)")
diff --git a/src/pymatlib/core/yaml_parser.py b/src/pymatlib/core/yaml_parser.py
index f6b92fcd65ba712b7a28077a922df717fe42a66f..60dcb51b42135b4c825736561b589377ba8ec69e 100644
--- a/src/pymatlib/core/yaml_parser.py
+++ b/src/pymatlib/core/yaml_parser.py
@@ -123,7 +123,6 @@ class MaterialConfigParser:
             raise ValueError("The 'properties' section in your YAML file must be a dictionary with key-value pairs")
         self._validate_property_names(properties)
         self._validate_required_fields()
-        self._validate_property_values(properties)
 
     def _validate_property_names(self, properties: Dict[str, Any]) -> None:
         """
@@ -190,6 +189,107 @@ class MaterialConfigParser:
             if prop_name in ['energy_density_solidus', 'energy_density_liquidus']:
                 raise ValueError(f"{prop_name} cannot be set directly. It is computed from other properties")
 
+    @staticmethod
+    def _validate_property_value(prop: str, value: Union[float, np.ndarray]) -> None:
+        """
+        Validate a property value or array of values against physical constraints.
+        Args:
+            prop (str): The name of the property being validated
+            value (Union[float, np.ndarray]): The value or array of values to validate
+        Raises:
+            ValueError: If the property value violates physical constraints
+            TypeError: If the property value has an invalid type
+        """
+        # Define property constraints with SI units
+        BASE_PROPERTIES = {'base_temperature', 'base_density'}  # always single float values
+        POSITIVE_PROPERTIES = {'density', 'heat_capacity', 'heat_conductivity', 'temperature',
+                               'dynamic_viscosity', 'kinematic_viscosity', 'thermal_diffusivity',
+                               'surface_tension'}
+        NON_NEGATIVE_PROPERTIES = {'latent_heat_of_fusion', 'latent_heat_of_vaporization', 'energy_density',
+                                   'energy_density_solidus', 'energy_density_liquidus', 'energy_density_array'}
+        ARRAY_PROPERTIES = {'temperature_array', 'energy_density_temperature_array', 'energy_density_array'}
+
+        # Property-specific range constraints
+        PROPERTY_RANGES = {
+            'base_temperature': (0, 5000),  # K
+            'temperature': (0, 5000),  # K
+            'base_density': (800, 22000),  # kg/m³
+            'density': (800, 22000),  # kg/m³
+            'heat_capacity': (100, 10000),  # J/(kg·K)
+            'heat_conductivity': (1, 600),  # W/(m·K)
+            'thermal_expansion_coefficient': (-5e-5, 3e-5),  # 1/K
+            'dynamic_viscosity': (1e-4, 1e5),  # Pa·s
+            'kinematic_viscosity': (1e-8, 1e-3),  # m²/s
+            'thermal_diffusivity': (1e-8, 1e-3),  # m²/s
+            'surface_tension': (0.1, 3.0),  # N/m
+            'latent_heat_of_fusion': (0, 600000),  # J/kg
+            'latent_heat_of_vaporization': (50000, 12000000),  # J/kg
+        }
+
+        try:
+            # Handle arrays (from file or key-val properties)
+            if isinstance(value, np.ndarray):
+                # Check for NaN or infinite values
+                if np.isnan(value).any():
+                    raise ValueError(f"Property '{prop}' contains NaN values.")
+                if np.isinf(value).any():
+                    raise ValueError(f"Property '{prop}' contains infinite values.")
+
+                # Property-specific validations for arrays
+                if prop in POSITIVE_PROPERTIES:
+                    if (value <= 0).any():
+                        bad_indices = np.where(value <= 0)[0]
+                        bad_values = value[value <= 0]
+                        raise ValueError(f"All '{prop}' values must be positive. Found {len(bad_indices)} invalid values "
+                                         f"at indices {bad_indices}: {bad_values}.")
+
+                if prop in NON_NEGATIVE_PROPERTIES or prop in ARRAY_PROPERTIES:
+                    if (value < 0).any():
+                        bad_indices = np.where(value < 0)[0]
+                        bad_values = value[value < 0]
+                        raise ValueError(f"All '{prop}' values must be non-negative. Found {len(bad_indices)} invalid values "
+                                         f"at indices {bad_indices}: {bad_values}.")
+
+                # Check range constraints if applicable
+                if prop in PROPERTY_RANGES:
+                    min_val, max_val = PROPERTY_RANGES[prop]
+                    if ((value < min_val) | (value > max_val)).any():
+                        out_of_range = np.where((value < min_val) | (value > max_val))[0]
+                        out_values = value[out_of_range]
+                        raise ValueError(f"'{prop}' contains values outside expected range ({min_val} to {max_val}) "
+                                         f"\n -> Found {len(out_of_range)} out-of-range values at indices {out_of_range}: {out_values}")
+
+            # Handle single values (from constant or computed properties)
+            else:
+                # Check for NaN or infinite values
+                if np.isnan(value):
+                    raise ValueError(f"Property '{prop}' is NaN.")
+                if np.isinf(value):
+                    raise ValueError(f"Property '{prop}' is infinite.")
+
+                # Type checking
+                if not isinstance(value, float):
+                    raise TypeError(f"Property '{prop}' must be a float, got {type(value).__name__}. "
+                                    f"\n -> Please use decimal notation (e.g., 1.0 instead of 1) or scientific notation.")
+
+                # Property-specific validations for single values
+                if prop in BASE_PROPERTIES or prop in POSITIVE_PROPERTIES:
+                    if value <= 0:
+                        raise ValueError(f"Property '{prop}' must be positive, got {value}.")
+
+                if prop in NON_NEGATIVE_PROPERTIES:
+                    if value < 0:
+                        raise ValueError(f"Property '{prop}' must be non-negative, got {value}.")
+
+                # Check range constraints if applicable
+                if prop in PROPERTY_RANGES:
+                    min_val, max_val = PROPERTY_RANGES[prop]
+                    if value < min_val or value > max_val:
+                        raise ValueError(f"Property '{prop}' value {value} is outside expected range ({min_val} to {max_val}).")
+
+        except Exception as e:
+            raise ValueError(f"Failed to validate property value \n -> {e}")
+
     ##################################################
     # Alloy Creation
     ##################################################
@@ -216,7 +316,7 @@ class MaterialConfigParser:
         except KeyError as e:
             raise ValueError(f"Configuration error: Missing {e}")
         except Exception as e:
-            raise ValueError(f"Failed to create alloy: {e}")
+            raise ValueError(f"Failed to create alloy \n -> {e}")
 
     def _get_elements(self) -> List[ChemicalElement]:
         """
@@ -236,19 +336,25 @@ class MaterialConfigParser:
     # Property Type Checking
     ##################################################
     @staticmethod
-    def _is_numeric(value: str) -> bool:
+    def _is_numeric(value: Any) -> bool:
         """
-        Check if string represents a number (including scientific notation).
+        Check if string represents a float number (including scientific notation).
         Args:
-            value (str): The string to check.
+            value (Any): The value to check.
         Returns:
-            bool: True if the string represents a number, False otherwise.
+            bool: True if the value represents a float, False otherwise.
         """
-        try:
-            float(value)
+        if isinstance(value, float):
             return True
-        except ValueError:
-            return False
+        if isinstance(value, str):
+            try:
+                float(value)
+                # return True
+                # Ensure it contains a decimal point or is in scientific notation
+                return '.' in value or 'e' in value.lower()
+            except ValueError:
+                return False
+        return False
 
     @staticmethod
     def _is_data_file(value: str | Dict[str, str]) -> bool:
@@ -265,14 +371,16 @@ class MaterialConfigParser:
         if isinstance(value, str):
             return value.endswith(('.txt', '.csv', '.xlsx'))
         # Advanced format: property_name: { file: "filename", temp_col: "col1", prop_col: "col2" }
-        if isinstance(value, dict) and 'file' in value and 'temp_col' in value and 'prop_col' in value:
+        if isinstance(value, dict) and 'file' in value:
             required_keys = {'file', 'temp_col', 'prop_col'}
             value_keys = set(value.keys())
-            if not required_keys.issubset(value_keys):
-                missing_keys = required_keys - value_keys
+            # Check for missing required keys
+            missing_keys = required_keys - value_keys
+            if missing_keys:
                 raise ValueError(f"Missing required keys for file configuration: {missing_keys}")
-            if value_keys != required_keys:
-                extra_keys = value_keys - required_keys
+            # Check for extra keys
+            extra_keys = value_keys - required_keys
+            if extra_keys:
                 raise ValueError(f"Extra keys found in file configuration: {extra_keys}")
             return True
         return False
@@ -288,17 +396,18 @@ class MaterialConfigParser:
         Raises:
             ValueError: If the key-val property configuration is invalid.
         """
-        if isinstance(value, dict) and 'key' in value and 'val' in value:
-            required_keys = {'key', 'val'}
+        required_keys = {'key', 'val'}
+        # Check if it looks like it's trying to be a key-val property
+        if isinstance(value, dict) and any(k in value for k in required_keys):
             value_keys = set(value.keys())
-
-            if value_keys != required_keys:
-                missing_keys = required_keys - value_keys
-                extra_keys = value_keys - required_keys
-                if missing_keys:
-                    raise ValueError(f"Missing required keys for key-val property: {missing_keys}")
-                if extra_keys:
-                    raise ValueError(f"Extra keys found in key-val property: {extra_keys}")
+            # Check for missing required keys
+            missing_keys = required_keys - value_keys
+            if missing_keys:
+                raise ValueError(f"Missing required keys for key-val property: {missing_keys}")
+            # Check for extra keys
+            extra_keys = value_keys - required_keys
+            if extra_keys:
+                raise ValueError(f"Extra keys found in key-val property: {extra_keys}")
             return True
         return False
 
@@ -313,19 +422,23 @@ class MaterialConfigParser:
         Raises:
             ValueError: If the compute property configuration is invalid.
         """
-        if isinstance(value, str) and value == 'compute':
-            return True
-        elif isinstance(value, dict) and 'compute' in value:
+        # Simple format: property_name: compute
+        if isinstance(value, str):
+            if value == 'compute':
+                return True
+            elif value.startswith('compute'):
+                # Catch common mistakes like 'compute1'
+                raise ValueError(f"Invalid compute property value: '{value}'. Did you mean 'compute'?")
+        # Advanced format: property_name: { compute: "method_name" }
+        elif isinstance(value, dict) and any(k.startswith('compute') for k in value.keys()):
             required_keys = {'compute'}
             value_keys = set(value.keys())
-
-            if value_keys != required_keys:
-                missing_keys = required_keys - value_keys
-                extra_keys = value_keys - required_keys
-                if missing_keys:
-                    raise ValueError(f"Missing required key for compute property: {missing_keys}")
-                if extra_keys:
-                    raise ValueError(f"Extra keys found in compute property: {extra_keys}")
+            missing_keys = required_keys - value_keys
+            extra_keys = value_keys - required_keys
+            if missing_keys:
+                raise ValueError(f"Missing required key for compute property: {missing_keys}")
+            if extra_keys:
+                raise ValueError(f"Extra keys found in compute property: {extra_keys}")
             return True
         return False
 
@@ -338,18 +451,23 @@ class MaterialConfigParser:
         Returns:
             PropertyType: The determined property type.
         """
-        if isinstance(config, float) or (isinstance(config, str) and self._is_numeric(config)):
-            return PropertyType.CONSTANT
-        elif self._is_data_file(config):
-            return PropertyType.FILE
-        elif self._is_key_val_property(config):
-            return PropertyType.KEY_VAL
-        elif self._is_compute_property(config):
-            return PropertyType.COMPUTE
-        elif prop_name == 'energy_density_temperature_array' and isinstance(config, str) and config.startswith('(') and config.endswith(')'):
-            return PropertyType.TUPLE_STRING
-        else:
-            return PropertyType.INVALID
+        try:
+            if isinstance(config, int):
+                raise ValueError(f"Property '{prop_name}' must be defined as a float, got {config} of type {type(config).__name__}")
+            if self._is_numeric(config):
+                return PropertyType.CONSTANT
+            elif self._is_data_file(config):
+                return PropertyType.FILE
+            elif self._is_key_val_property(config):
+                return PropertyType.KEY_VAL
+            elif self._is_compute_property(config):
+                return PropertyType.COMPUTE
+            elif prop_name == 'energy_density_temperature_array' and isinstance(config, str) and config.startswith('(') and config.endswith(')'):
+                return PropertyType.TUPLE_STRING
+            else:
+                return PropertyType.INVALID
+        except Exception as e:
+            raise ValueError(f"Failed to determine property type \n -> {e}")
 
     def _categorize_properties(self, properties: Dict[str, Any]) -> Dict[PropertyType, List[Tuple[str, Any]]]:
         """
@@ -369,10 +487,14 @@ class MaterialConfigParser:
             PropertyType.TUPLE_STRING: []
         }
         for prop_name, config in properties.items():
-            prop_type = self._determine_property_type(prop_name, config)
-            if prop_type == PropertyType.INVALID:
-                raise ValueError(f"Invalid configuration for property '{prop_name}': {config}")
-            categorized_properties[prop_type].append((prop_name, config))
+            try:
+                prop_type = self._determine_property_type(prop_name, config)
+                if prop_type == PropertyType.INVALID:
+                    raise ValueError(f"Invalid configuration format for property '{prop_name}': {config}")
+                categorized_properties[prop_type].append((prop_name, config))
+            except Exception as e:
+                # Provide more context in the error message
+                raise ValueError(f"Failed to categorize properties \n -> {e}")
         return categorized_properties
 
     ##################################################
@@ -405,26 +527,28 @@ class MaterialConfigParser:
                         # Handle tuple string properties if needed
                         pass
         except Exception as e:
-            raise ValueError(f"Failed to process properties: {e}")
+            raise ValueError(f"Failed to process properties \n -> {e}")
 
 ########################################################################################################################
 
     @staticmethod
-    def _process_constant_property(alloy: Alloy, prop_name: str, prop_config: Union[int, float, str]) -> None:
+    def _process_constant_property(alloy: Alloy, prop_name: str, prop_config: Union[float, str]) -> None:
         """
         Process constant float property.
         Args:
             alloy (Alloy): The alloy object to update.
             prop_name (str): The name of the property to set.
-            prop_config (Union[int, float, str]): The property value or string representation.
+            prop_config (Union[float, str]): The property value or string representation.
         Raises:
-            ValueError: If the property value cannot be converted to float.
+            ValueError: If the property value cannot be converted to float or violates constraints.
         """
         try:
             value = float(prop_config)
+            # Validate the value
+            MaterialConfigParser._validate_property_value(prop_name, value)
             setattr(alloy, prop_name, value)
         except (ValueError, TypeError) as e:
-            error_msg = f"Invalid number format for {prop_name}: {prop_config}"
+            error_msg = f"Failed to process constant property \n -> {e}"
             raise ValueError(error_msg) from e
 
 ########################################################################################################################
@@ -451,9 +575,11 @@ class MaterialConfigParser:
                 # For string configuration, construct the full path
                 file_path = str(yaml_dir / file_config)
                 temp_array, prop_array = read_data_from_file(file_path)
+            # Validate the property array
+            self._validate_property_value(prop_name, prop_array)
             self._process_property_data(alloy, prop_name, T, temp_array, prop_array)
         except Exception as e:
-            error_msg = f"Error processing file property {prop_name}: {str(e)}"
+            error_msg = f"Failed to process file property {prop_name} \n -> {str(e)}"
             raise ValueError(error_msg) from e
 
 ########################################################################################################################
@@ -474,9 +600,11 @@ class MaterialConfigParser:
             val_array = np.array(prop_config['val'], dtype=float)
             if len(key_array) != len(val_array):
                 raise ValueError(f"Length mismatch in {prop_name}: key and val arrays must have same length")
+            # Validate the value array
+            self._validate_property_value(prop_name, val_array)
             self._process_property_data(alloy, prop_name, T, key_array, val_array)
         except Exception as e:
-            error_msg = f"Error processing key-val property {prop_name}: {str(e)}"
+            error_msg = f"Failed to proces key-val property '{prop_name}' \n -> {str(e)}"
             raise ValueError(error_msg) from e
 
     def _process_key_definition(self, key_def, val_array, alloy: Alloy) -> np.ndarray:
@@ -499,7 +627,7 @@ class MaterialConfigParser:
             else:
                 raise ValueError(f"Invalid key definition: {key_def}")
         except Exception as e:
-            error_msg = f"Error processing key definition: {str(e)}"
+            error_msg = f"Failed to process key definition \n -> {str(e)}"
             raise ValueError(error_msg) from e
 
     @staticmethod
@@ -522,7 +650,7 @@ class MaterialConfigParser:
             key_array = np.arange(start, start + increment * n_points, increment)
             return key_array
         except Exception as e:
-            error_msg = f"Invalid equidistant format: {key_def}. Error: {str(e)}"
+            error_msg = f"Invalid equidistant format: {key_def} \n -> {str(e)}"
             raise ValueError(error_msg) from e
 
     @staticmethod
@@ -552,7 +680,7 @@ class MaterialConfigParser:
             key_array = np.array(processed_key, dtype=float)
             return key_array
         except Exception as e:
-            error_msg = f"Error processing list key: {str(e)}"
+            error_msg = f"Error processing list key \n -> {str(e)}"
             raise ValueError(error_msg) from e
 
     ##################################################
@@ -579,7 +707,7 @@ class MaterialConfigParser:
             else:
                 raise ValueError(f"Unexpected type for T: {type(T)}")
         except Exception as e:
-            error_msg = f"Error processing property data for {prop_name}: {str(e)}"
+            error_msg = f"Error processing property data for '{prop_name}' \n -> {str(e)}"
             raise ValueError(error_msg) from e
 
     def _process_symbolic_temperature(self, alloy: Alloy, prop_name: str, T: sp.Symbol, temp_array: np.ndarray, prop_array: np.ndarray) -> None:
@@ -831,7 +959,7 @@ class MaterialConfigParser:
             else:
                 return self._process_int_step(start, end, int(step))
         except ValueError as e:
-            raise ValueError(f"Invalid temperature array definition: {e}")
+            raise ValueError(f"Invalid temperature array definition \n -> {e}")
 
     @staticmethod
     def _process_float_step(start: float, end: float, delta: float) -> np.ndarray:
diff --git a/src/pymatlib/data/alloys/SS304L/SS304L.yaml b/src/pymatlib/data/alloys/SS304L/SS304L.yaml
index 5cb9ea99157b56668f261653e5fc3f2207e1288e..e17cfc717e14a8b786d631f8d104f07bf6d44fc3 100644
--- a/src/pymatlib/data/alloys/SS304L/SS304L.yaml
+++ b/src/pymatlib/data/alloys/SS304L/SS304L.yaml
@@ -125,8 +125,8 @@ composition:
   Ni: 0.0806
   Fe: 0.70695
 
-solidus_temperature: 1605
-liquidus_temperature: 1735
+solidus_temperature: 1605.
+liquidus_temperature: 1735.
 
 
 properties:
diff --git a/src/pymatlib/data/alloys/SS304L/SS304L_comprehensive.yaml b/src/pymatlib/data/alloys/SS304L/SS304L_comprehensive.yaml
index 1db622cdc76c5e1c80058ae76c559b634916d1bc..7d2278a33c7158e6e4304c4035571d21481ecc5d 100644
--- a/src/pymatlib/data/alloys/SS304L/SS304L_comprehensive.yaml
+++ b/src/pymatlib/data/alloys/SS304L/SS304L_comprehensive.yaml
@@ -7,12 +7,12 @@ composition:
   Mo: 0.025
   Mn: 0.010
 
-solidus_temperature: 1605
-liquidus_temperature: 1735
+solidus_temperature: 1605.
+liquidus_temperature: 1735.
 
 properties:
   # 1. Constant float property
-  density: 7950.  # kg/m³
+  density: compute  # kg/m³
 
   # 2.1 File-based property (simple format)
   heat_conductivity: ./heat_conductivity_temperature.txt